zoukankan      html  css  js  c++  java
  • 【bzoj3600】没有人的算术

    因为阿咸,所以不会写题解。

    大概就是平衡树维护大小关系然后随意线段树就好。

    每次更新一下线段树上的区间max

    #include<bits/stdc++.h>
    #define ll long long
    #define alpha 0.7
    #define maxn 500005
    #define INF 1ll<<60
    
    using namespace std;
    
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    ll tag[maxn];
    
    struct node{
        int first,second;
        node(int first,int second):first(first),second(second){};
        node(){};
        friend bool operator == (node A,node B){
            return (A.first==B.first)&&(A.second==B.second);
        }
        friend bool operator < (node A,node B){
            if(tag[A.first]==tag[B.first])return tag[A.second]<tag[B.second];
            return tag[A.first]<tag[B.first];
        }
    };
    
    int n,m,tmp,root,pos[maxn];
    
    struct sctree{
        int top,cnt,size[maxn],id[maxn],ch[maxn][2];
        node val[maxn];
        inline void pushup(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1;}
        inline void build(int &x,int l,int r,ll lv,ll rv){
            if(l>r){x=0;return;}
            if(l==r){
                x=id[l];size[x]=1;
                tag[x]=lv+rv>>1;
                ch[x][0]=ch[x][1]=0;
                return;
            }
            int mid=l+r>>1;
            x=id[mid];tag[x]=lv+rv>>1;
            build(ch[x][0],l,mid-1,lv,tag[x]-1);
            build(ch[x][1],mid+1,r,tag[x]+1,rv);
            pushup(x);
        }
        inline void dfs(int x){
            if(!x)return;
            dfs(ch[x][0]);
            id[++top]=x;
            dfs(ch[x][1]);
        }
        inline void rebuild(int &x,ll lv,ll rv){
            top=0;
            dfs(x);
            build(x,1,top,lv,rv);
        }
        inline int insert(int &x,ll lv,ll rv,node v){
            if(!x){
                x=++cnt;size[x]=1;
                tag[x]=lv+rv>>1;
                val[x]=v;
                return x;
            }
            if(val[x]==v)return x;
            int p;
            ll mid=lv+rv>>1;
            if(v<val[x])p=insert(ch[x][0],lv,mid-1,v);
            else p=insert(ch[x][1],mid+1,rv,v);
            pushup(x);
            if(1.0*size[x]*alpha>1.0*max(size[ch[x][0]],size[ch[x][1]])){
                if(tmp){
                    if(ch[x][0]==tmp)rebuild(ch[x][0],lv,mid-1);
                    else rebuild(ch[x][1],mid+1,rv);
                    tmp=0;
                }
            }else tmp=x;
            return p;
        }
    }T1;
    
    int Max;
    
    struct Segment_Tree{
        int mx[maxn];
        inline void pushup(int o){
            int ls=mx[o<<1],rs=mx[o<<1|1];
            if(tag[pos[ls]]<tag[pos[rs]])mx[o]=rs;else mx[o]=ls;
        }
        inline void build(int o,int l,int r){
            if(l==r){
                mx[o]=l;
                return;
            }
            int mid=l+r>>1;
            build(o<<1,l,mid);
            build(o<<1|1,mid+1,r);
            pushup(o);
        }
        inline void change(int o,int l,int r,int x){
            if(l==r){
                mx[o]=l;
                return;
            }
            int mid=l+r>>1;
            if(x<=mid)change(o<<1,l,mid,x);
            else change(o<<1|1,mid+1,r,x);
            pushup(o);
        }
        inline void query(int o,int l,int r,int x,int y){
            if(x<=l&&r<=y){
                if(tag[pos[Max]]<tag[pos[mx[o]]])Max=mx[o];
                return;
            }
            int mid=l+r>>1;
            if(y<=mid)query(o<<1,l,mid,x,y);
            else if(x>mid)query(o<<1|1,mid+1,r,x,y);
            else {
                query(o<<1,l,mid,x,mid);
                query(o<<1|1,mid+1,r,mid+1,y);
            }
        }
    }T2;
    
    char ch[2];
    
    int main(){
        n=read();m=read();tag[0]=-1;
        T1.insert(root,0,INF,node(0,0));
        for(int i=1;i<=n;++i)pos[i]=1;
        T2.build(1,1,n);
        int f1,f2,f3;
        for(int i=1;i<=m;++i){
            scanf("%s",ch);f1=read();f2=read();
            if(ch[0]=='C'){
                f3=read();
                pos[f3]=T1.insert(root,0,INF,node(pos[f1],pos[f2]));
                if(tmp){T1.rebuild(root,0,INF);tmp=0;}
                T2.change(1,1,n,f3);
            }else{
                Max=0;
                T2.query(1,1,n,f1,f2);
                printf("%d
    ",Max);
            }
        }
        return 0;
    }
  • 相关阅读:
    OK335x mksd.sh hacking
    Qt jsoncpp 对象拷贝、删除、函数调用 demo
    OK335xS 256M 512M nand flash make ubifs hacking
    Qt QScrollArea and layout in code
    JsonCpp Documentation
    Qt 4.8.5 jsoncpp lib
    Oracle数据库生成UUID
    freemarker得到数组的长度
    FreeMarker中if标签内的判断条件
    freemarker语法
  • 原文地址:https://www.cnblogs.com/illya/p/7545287.html
Copyright © 2011-2022 走看看