CF853

CF853A

容易想到的贪心思路:每次让c值最大的先飞。

区间取最大值&带修 可以线段树/堆维护

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define inl inline
#define ll long long 
#define endl '\n'
#define int ll
#define ls k<<1
#define rs k<<1|1
#define mid (l+r>>1)
const int N=3e5+5;
const int M=1e5+5;
const int inf=0x3f3f3f3f;
const int base=131;
const int mod=1e9+7;
inl int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return x*f;
}
inl void write(int x){
    if(x<0)putchar('-'),x=-x;
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
inl void writei(int x){write(x);putchar(' ');}
inl void writel(int x){write(x);putchar(endl);}
bool st;
int n,k,c[N],sum,ans,m,res[N];
bool ed;
struct segtree{
    int ma[N<<2],pos[N<<2],idx[N<<2];
    inl void pushup(int k){
        if(ma[ls]>=ma[rs]){
            pos[k]=pos[ls];
            ma[k]=ma[ls];
            idx[k]=idx[ls];
        }else{
            pos[k]=pos[rs];
            ma[k]=ma[rs];
            idx[k]=idx[rs];
        }
    }
    inl void build(int k,int l,int r){
        if(l==r)return pos[k]=l,ma[k]=c[l],idx[k]=l,void();
        build(ls,l,mid);build(rs,mid+1,r);
        pushup(k);
    }
    inl void modify(int k,int l,int r,int x,int v,int id){
        if(l==r)return ma[k]=v,idx[k]=id,void();
        if(x<=mid)modify(ls,l,mid,x,v,id);
        else modify(rs,mid+1,r,x,v,id);
        pushup(k);
    }
}SGT;
signed main(){
    n=read();k=read();
    for(int i=1;i<=n;i++)c[i]=read();
    for(int i=2;i<=k+1;i++){
        if(i-1<=n)sum+=c[i-1];
        ans+=sum;
    }
    if(k+1<=n)sum+=c[k+1];
    m=min(k+1,n);
    SGT.build(1,1,m);
    for(int i=1;i<=n-m;i++){
        int x=SGT.pos[1],v=SGT.ma[1],id=SGT.idx[1];
        sum-=v;ans+=sum;sum+=c[k+1+i];res[id]=k+i;
        SGT.modify(1,1,m,x,c[k+1+i],k+1+i);
    }
    for(int i=1;i<=m;i++){
        int x=SGT.pos[1],v=SGT.ma[1],id=SGT.idx[1];
        sum-=v;ans+=sum;res[id]=k+n-m+i;
        SGT.modify(1,1,m,x,0,0);
    }
    writel(ans);
    for(int i=1;i<=n;i++)writei(res[i]);
    return 0;
}

CF853B

维护每个时间能到的人数/总共花费 求出最早所有人都能到的时间 离开同理

贪心即可。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define inl inline
#define ll long long 
#define endl '\n'
#define int ll
const int N=1e6+5;
const int M=1e5+5;
const int inf=0x3f3f3f3f3f3f3f3f;
const int base=131;
const int mod=1e9+7;
inl int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return x*f;
}
inl void write(int x){
    if(x<0)putchar('-'),x=-x;
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
inl void writei(int x){write(x);putchar(' ');}
inl void writel(int x){write(x);putchar(endl);}
bool st;
int n,m,k,d,f,tt,c,csta[N],cstb[N],cnt,s,t,a[N],b[N],ans=inf;
vector<pair<int,int>>come[N],leave[N];
bool ed;
signed main(){
    n=read();m=read();k=read()+2;
    for(int i=1;i<=m;i++){
        d=read();f=read();tt=read();c=read();
        if(!tt)come[d].push_back({f,c});
        else leave[d].push_back({tt,c});
    }
    for(int i=1;i<=1e6;i++){
        a[i]=a[i-1];
        for(auto j:come[i]){
            int x=j.first,v=j.second;
            if(!csta[x])cnt++,a[i]+=v,csta[x]=v;
            else if(v<csta[x])a[i]+=v-csta[x],csta[x]=v;
        }
        if(!s&&cnt==n)s=i;
    }
    cnt=0;
    for(int i=1e6;i;i--){
        b[i]=b[i+1];
        for(auto j:leave[i]){
            int x=j.first,v=j.second;
            if(!cstb[x])cnt++,b[i]+=v,cstb[x]=v;
            else if(v<cstb[x])b[i]+=v-cstb[x],cstb[x]=v;
        }
        if(!t&&cnt==n)t=i;
    }
    if(!s||!t||t-s+1<k){puts("-1");return 0;}
    for(int i=s;i+k-1<=t;i++)ans=min(ans,a[i]+b[i+k-1]);
    writel(ans);
    return 0;
}

CF853C

n个点好矩阵的个数:\(n*(n-1)/2\)

考虑容斥:用右上角的数量-左上角左边-右下角下边+左下角下边

二位数点 树状数组离线求即可

口胡完毕 代码咕了

CF853D

发现所有 \(a_i\) 除100之后没有影响

考虑dp:攒积分/花积分两种分别转移

这里积分最多攒到40 再多就没必要了

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define inl inline
#define ll long long 
#define endl '\n'
#define int ll
const int N=3e5+5;
const int M=1e5+5;
const int inf=0x3f3f3f3f3f3f3f3f;
const int base=131;
const int mod=1e9+7;
inl int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return x*f;
}
inl void write(int x){
    if(x<0)putchar('-'),x=-x;
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
inl void writei(int x){write(x);putchar(' ');}
inl void writel(int x){write(x);putchar(endl);}
bool st;
int n,a[N],f[N][45];
bool ed;
signed main(){
    n=read();
    for(int i=1;i<=n;i++)a[i]=read()/100;
    memset(f,0x3f,sizeof f);
    f[0][0]=0;
    for(int i=1;i<=n;i++){
        for(int j=0;j<=40;j++){
            if(j-a[i]/10>=0)f[i][j]=min(f[i][j],f[i-1][j-a[i]/10]+a[i]);
            for(int k=0;k<=a[i]&&k+j<=40;k++)
                f[i][j]=min(f[i][j],f[i-1][j+k]+a[i]-k);
        }
    }
    int ans=inf;
    for(int i=0;i<=40;i++)ans=min(ans,f[n][i]);
    writel(ans*100);
    return 0;
}

E题3400不会不丢人/kel

posted @ 2023-11-21 15:00  xiang_xiang  阅读(100)  评论(0)    收藏  举报