• BZOJ 4399: 魔法少女LJJ(线段树)


    传送门

    解题思路

      出题人真会玩。。操作(2)线段树合并,然后每棵线段树维护元素个数和。对于(6)这个询问,因为乘积太大,所以要用对数。时间复杂度(O(nlogn))

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
     
    using namespace std;
    const int N=400005;
    const int M=2000005;
     
    inline int rd(){
        int x=0,f=1; char ch=getchar();
        while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
        return f?x:-x;  
    }
     
    int m,tot,rt[M],F[M],num,cpy[N],cnt,a[N],u,tmp;
     
    struct Query{
        int op,x,y;
    }q[N];
     
    struct Segment_Tree{
        double Mul[M];
        int siz[M],ls[M],rs[M];
        void update(int &x,int l,int r,int s,int k,double now){
            if(!x) x=++tot; siz[x]+=s; Mul[x]+=s*now;
            if(l==r) return; int mid=(l+r)>>1;
            if(k<=mid) update(ls[x],l,mid,s,k,now);
            else update(rs[x],mid+1,r,s,k,now);
        }   
        int merge(int x,int y,int l,int r){
            if(!x || !y) return (x|y);
            if(l==r) {siz[x]+=siz[y]; Mul[x]+=Mul[y]; return x;}
            int mid=(l+r)>>1;
            ls[x]=merge(ls[x],ls[y],l,mid);
            rs[x]=merge(rs[x],rs[y],mid+1,r);
            siz[x]=siz[ls[x]]+siz[rs[x]];
            Mul[x]=Mul[ls[x]]+Mul[rs[x]];
            return x;
        }
        void erase(int x,int l,int r,int L,int R){
            if(L>R || !siz[x]) return;
            if(l==r) {tmp+=siz[x]; siz[x]=0; Mul[x]=0; return;}
            int mid=(l+r)>>1;
            if(L<=mid) erase(ls[x],l,mid,L,R);
            if(mid<R) erase(rs[x],mid+1,r,L,R);
            siz[x]=siz[ls[x]]+siz[rs[x]];
            Mul[x]=Mul[ls[x]]+Mul[rs[x]];
        }
        int kth(int x,int l,int r,int k){
            if(l==r) return l; int mid=(l+r)>>1;
            if(siz[ls[x]]>=k) return kth(ls[x],l,mid,k);
            else {k-=siz[ls[x]]; return kth(rs[x],mid+1,r,k);}
        }
    }tree;
     
    int get(int x){
        if(x==F[x]) return x;
        return F[x]=get(F[x]);
    }   
     
    int main(){
        m=rd(); int x,y,uu,vv;
        for(int i=1;i<=m;i++){
            q[i].op=rd(),q[i].x=rd();
            if(q[i].op==1) cpy[++cnt]=q[i].x;
            if(q[i].op==1 || q[i].op==7) continue; q[i].y=rd();
            if(q[i].op==3 || q[i].op==4) cpy[++cnt]=q[i].y;
        }
        sort(cpy+1,cpy+1+cnt); u=unique(cpy+1,cpy+1+cnt)-cpy-1;
        for(int i=1;i<=m;i++){
            if(q[i].op==1){
                x=lower_bound(cpy+1,cpy+1+u,q[i].x)-cpy;
                num++; F[num]=num; tree.update(rt[num],1,u,1,x,log(q[i].x));
            }
            else if(q[i].op==2){
                x=q[i].x,y=q[i].y; uu=get(x),vv=get(y);
                if(uu==vv) continue; F[vv]=uu;
                rt[uu]=tree.merge(rt[uu],rt[vv],1,u);
            }
            else if(q[i].op==3){
                x=q[i].x,y=lower_bound(cpy+1,cpy+1+u,q[i].y)-cpy;
                tmp=0; x=get(x); tree.erase(rt[x],1,u,1,y-1);
                if(tmp) tree.update(rt[x],1,u,tmp,y,log(q[i].y));
            }   
            else if(q[i].op==4){
                x=q[i].x,y=lower_bound(cpy+1,cpy+1+u,q[i].y)-cpy;   
                tmp=0; x=get(x); tree.erase(rt[x],1,u,y+1,u);
                if(tmp) tree.update(rt[x],1,u,tmp,y,log(q[i].y));
            }
            else if(q[i].op==5){
                x=q[i].x; y=q[i].y; x=get(x);
                printf("%d
    ",cpy[tree.kth(rt[x],1,u,y)]);  
            }
            else if(q[i].op==6) {
                x=get(q[i].x); y=get(q[i].y);
                puts(tree.Mul[rt[x]]>tree.Mul[rt[y]]?"1":"0");   
            }
            else if(q[i].op==7) printf("%d
    ",tree.siz[rt[get(q[i].x)]]);
        }
        return 0;
    }
    
  • 相关阅读:
    scrapy 常用代码
    pycahrm 基础设置
    pycahrm 激活
    pycharm 常用快捷键
    platform 系统是windows还是liunx
    (14)awk布尔值、比较和逻辑运算
    (13)gawk支持的正则表达式
    (12)awk数据类型和字面量
    (11)细说awk中的变量和变量赋值
    (10)print、printf、sprintf和重定向
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/10356472.html
Copyright © 2020-2023  润新知