11.6考试爆炸记

boom…
100→50
(1)blash
队列操作题,自带双指针

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
inline int read(){
    int i=0,f=1;
    char ch;
    for(ch=getchar();!isdigit(ch);ch=getchar())
        if(ch=='-') f=-1;
    for(;isdigit(ch);ch=getchar())
        i=(i<<3)+(i<<1)+(ch^48);
    return i*f;
}
int buf[1024];
inline void write(long long x){
    if(!x){putchar('0');return ;}
    if(x<0){putchar('-');x=-x;}
    while(x){buf[++buf[0]]=x%10,x/=10;}
    while(buf[0]) putchar(buf[buf[0]--]+48);
    return ;
}
#define stan 1111111
int a,n,p2,p3,sze;
long long tmp2,tmp3,que[stan],tmp;
signed main(){
    while(scanf("%d%d",&a,&n)!=EOF){
        sze=2;
        que[1]=a;
        p2=1;p3=1;
        while(sze<=n){
            tmp2=que[p2]*2+1;
            tmp3=que[p3]*3+1;
            tmp=min(tmp2,tmp3);
            if(tmp2else
                ++p3;
            if(tmp==que[sze-1]) continue;
            que[sze++]=tmp;
        }
        write(que[n]);
        puts("");
    }
    return 0;
}

(2)序列操作
二分判定性问题
其实因为 h[i] 小于 10000 也可以桶操作
不过不要手贱乱减
桶操作版

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
inline int read(){
    int i=0,f=1;
    char ch;
    for(ch=getchar();!isdigit(ch);ch=getchar())
        if(ch=='-') f=-1;
    for(;isdigit(ch);ch=getchar())
        i=(i<<3)+(i<<1)+(ch^48);
    return i*f;
}
int buf[1024];
inline void write(int x){
    if(!x){putchar('0');return ;}
    if(x<0){putchar('-');x=-x;}
    while(x){buf[++buf[0]]=x%10,x/=10;}
    while(buf[0]) putchar(buf[buf[0]--]+48);
    return ;
}
#define stan 1111111
#define sten 11111
int n,m,h[stan],c[stan],sze[sten],tmp[sten],pos;
signed main(){
    n=read();m=read();
    for(int i=1;i<=n;++i)
        h[i]=read();
    sort(h+1,h+n+1);
    for(int i=1;i<=m;++i)
        c[i]=read();
    if(m<=1000&&n<=1000){
        for(int i=1;i<=m;++i){
            for(int j=n;j>n-c[i];--j)
                if(h[j]==0){
                    write(i-1);
                    return 0;
                }else --h[j];
            sort(h+1,h+n+1);
        }
        write(m);
        return 0;
    }else{
        for(register int i=1;i<=n;++i){
            ++sze[h[i]];pos=max(h[i],pos);
        }
        for(register int i=1;i<=m;++i){
            for(register int j=pos;j;--j){
                if(sze[j]>=c[i]){
                    sze[j]=sze[j]-c[i];
                    sze[j-1]+=c[i];
                    sze[j]+=tmp[j];
                    tmp[j]=0;
                    c[i]=0;
                    break;
                }else if(sze[j]>0){
                    c[i]-=sze[j];
                    tmp[j-1]=sze[j];
                    sze[j]=tmp[j];
                    tmp[j]=0;
                }else if(tmp[j]){
                    sze[j]=tmp[j];
                    tmp[j]=0;
                }
            }
            if(c[i]>0){
                write(i-1);
                return 0;
            }
        }
        write(m);
        return 0;
    }
}

巧妙的二分

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
inline int read(){
    int i=0,f=1;
    char ch;
    for(ch=getchar();!isdigit(ch);ch=getchar())
        if(ch=='-') f=-1;
    for(;isdigit(ch);ch=getchar())
        i=(i<<3)+(i<<1)+(ch^48);
    return i*f;
}
int buf[1024];
inline void write(long long x){
    if(!x){putchar('0');return ;}
    if(x<0){putchar('-');x=-x;}
    while(x){buf[++buf[0]]=x%10,x/=10;}
    while(buf[0]) putchar(buf[buf[0]--]+48);
    return ;
}
#define stan 1111111
long long sum,val,cnt[stan],h[stan];
int n,m,c[stan];
bool check(int k){
    for(int i=0;i<=n+1;++i)
        cnt[i]=0;
    sum=0;val=0;
    for(int i=1;i<=k;++i){
        if(c[i]>n) return false;
        ++cnt[c[i]];
        sum+=c[i];
    }
    for(int i=n;i;--i)
        cnt[i]+=cnt[i+1];
    for(int i=1;i<=n;++i){
        val+=min(cnt[i],h[i]);
        if(h[i]1]+=cnt[i]-h[i];
    }
    return val==sum;
}
signed main(){
    n=read();m=read();
    for(int i=1;i<=n;++i)
        h[i]=read();
    sort(h+1,h+n+1);
    reverse(h+1,h+n+1);
    for(int i=1;i<=m;++i)
        c[i]=read();
    int l=0,r=m,ans=0;
    while(l<=r){
        int mid=l+r>>1;
        if(check(mid)){
            ans=mid;
            l=mid+1;
        }else r=mid-1;
    }
    write(ans);
    return 0;
}

(3)序列操作
LCT

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
inline int read(){
    int i=0,f=1;
    char ch;
    for(ch=getchar();!isdigit(ch);ch=getchar())
        if(ch=='-') f=-1;
    for(;isdigit(ch);ch=getchar())
        i=(i<<3)+(i<<1)+(ch^48);
    return i*f;
}
int buf[1024];
inline void write(long long x){
    if(!x){putchar('0');return ;}
    if(x<0){putchar('-');x=-x;}
    while(x){buf[++buf[0]]=x%10,x/=10;}
    while(buf[0]) putchar(buf[buf[0]--]+48);
    return ;
}
using namespace std;
#define stan 111111
#define sten 222222
struct edge{
    int x,y,k;
    friend bool operator < (edge a,edge b){
        return a.kint n,A,B,q;
struct query{
    int v,id;
    friend bool operator<(query a,query b){
        return a.vint fath[stan];
struct node{
    int s[2];
    int id,val;
    bool tag;
}tree[stan*2];
int val[stan*2];
int fa[stan*2];
long long ans[stan];
inline int getfa(int x){
    return (fath[x]==x)?fath[x]:fath[x]=getfa(fath[x]);
}
void gettree(edge *e,int t){
    for(int i=1;i<=n;++i)
        fath[i]=i;
    sort(e+1,e+1+t);
    int u=0;
    for(int i=1;i<=t;++i){
        int x=e[i].x,y=e[i].y;
        int fx=getfa(x),fy=getfa(y);
        if (fx==fy)continue;
        fath[fx]=fy;
        e[++u]=e[i];
    }
}
int key[stan];
int k;
void down(int x){
    if(tree[x].tag){
        swap(tree[x].s[0],tree[x].s[1]);
        tree[tree[x].s[0]].tag^=1;
        tree[tree[x].s[1]].tag^=1;
        tree[x].tag=0;
    }
    return ;
}
void update(int x){
    tree[x].val=val[x];tree[x].id=x;
    if(tree[x].s[0]&&tree[tree[x].s[0]].val>tree[x].val)
        tree[x].val=tree[tree[x].s[0]].val,tree[x].id=tree[tree[x].s[0]].id;
    if(tree[x].s[1]&&tree[tree[x].s[1]].val>tree[x].val)
        tree[x].val=tree[tree[x].s[1]].val,tree[x].id=tree[tree[x].s[1]].id;
    return ;
}
int pd(int x){
    if(x==tree[fa[x]].s[0])
        return 0;
    else if(x==tree[fa[x]].s[1])
        return 1;
    else return -1;
}
void rotate(int x){
    int y=fa[x],z=fa[y];
    int tx=pd(x),ty=pd(y);
    if (ty!=-1)tree[z].s[ty]=x;
    fa[x]=z;
    if(tree[x].s[tx^1])
        fa[tree[x].s[tx^1]]=y;
    tree[y].s[tx]=tree[x].s[tx^1];
    tree[x].s[tx^1]=y;
    fa[y]=x;
    update(y),update(x);
    if (ty!=-1)update(z);
}
int sta[stan*2],tp;
void clear(int x){
    tp=0;
    for(;pd(x)!=-1;x=fa[x])
        sta[++tp]=x;
    sta[++tp]=x;
    for(int i=tp;i;--i)
        down(sta[i]);
    return ;
}
void splay(int x){
    clear(x);
    for(;pd(x)!=-1;){
        if (pd(fa[x])!=-1){
            if(pd(x)==pd(fa[x])) rotate(fa[x]);
            else rotate(x);
        }
        rotate(x);
    }
    return ;
}
void split(int x){
    down(x);
    if(!tree[x].s[1]) return;
    tree[x].s[1]=0;
    update(x);
    return ;
}
void merge(int x,int y){
    tree[x].s[1]=y;
    update(x);
}
void access(int x){
    splay(x),split(x);
    for(;fa[x];x=fa[x]){
        splay(fa[x]),split(fa[x]);
        merge(fa[x],x);
    }
}
void makeroot(int x){
    access(x),splay(x);
    tree[x].tag^=1;
}
signed main(){
    n=read();A=read();B=read();q=read();
    for(int i=1;i<=A;++i){
        edgea[i].x=read();edgea[i].y=read();edgea[i].k=read();
    }
    for(int i=1;i<=B;++i){
        edgeb[i].x=read();edgeb[i].y=read();edgeb[i].k=read();
    }
    gettree(edgea,A);
    gettree(edgeb,B);
    for(int i=1;i<=n;++i){
        tree[i].val=val[i]=-999999999;
        tree[i].id=i;
    }
    long long now=0;
    for(int i=1;iint x=edgea[i].x,y=edgea[i].y;
        makeroot(x),makeroot(y);
        splay(x),splay(y);
        fa[x]=fa[y]=n+i;
        tree[n+i].val=val[n+i]=edgea[i].k;
        tree[n+i].id=i;
        now=now+edgea[i].k;
    }
    for(int i=1;iint x=edgeb[i].x,y=edgeb[i].y;
        makeroot(x),access(y),splay(y);
        int t=tree[y].id;
        if(val[t]==-999999999) continue;
        splay(t);
        key[++k]=edgeb[i].k-val[t];
        fa[tree[t].s[0]]=fa[tree[t].s[1]]=0;
        makeroot(x),makeroot(y);
        fa[y]=x;
    }
    for(int i=1;i<=q;++i){
        que[i].v=read();
        que[i].id=i;
    }
    sort(que+1,que+1+q);
    sort(key+1,key+1+k);
    int w=1;
    for(int i=1;i<=q;++i){
        while(w<=k&&key[w]<=que[i].v*2)now=now+key[w++];
        ans[que[i].id]=now+1ll*que[i].v*(n-1-(w-1)*2);
    }
    for(int i=1;i<=q;++i){
        write(ans[i]);
        puts("");
    }
    return 0;
}

你可能感兴趣的:(OI,琐题集萃门,平衡树纲,数据结构门)