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;
    }
  • 相关阅读:
    .charAt()方法
    CustomerBiz方法运用
    面向对象_方法 判断
    方法
    查找无序数组索引
    面向对象_购票
    创建类 方法 构建类对象
    StringBuffer 方法
    docker创建redis mysql 等服务
    docker常用的命令
  • 原文地址:https://www.cnblogs.com/illya/p/7545287.html
Copyright © 2011-2022 走看看