[bzoj1146][CTSC2008]网络管理Network(dfs序+树状数组套主席树)

来源:互联网 发布:苏州优才通网络怎么样 编辑:程序博客网 时间:2024/05/18 06:40

再发一波福利,还是老规矩,不许说啊。
传送门
其实就是搞下来dfs序,然后差分
具体细节自己想想怎么处理
然后就是这题最恶心的空间
我死活卡在257MB
然后我就放弃卡
正规地先建一棵静态,然后修改在dfs序上改
这样就是O(nlogn+m(update)log2n)
所以只开了89MB
代码:

#include<cstdio>#include<algorithm>#define ll long longusing namespace std;inline int read(){    int x=0;char ch=' ';int f=1;    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();    if(ch=='-')f=-1,ch=getchar();    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();    return x*f;}const int N=8e4+5;const int M=N*85;struct node{    int ls,rs,size;}t[M];int n,m,cnt,tot,hash_cnt;int a[N],dfn_clock;int v[N],b[N<<1];inline int Hash(int x){    return lower_bound(b+1,b+hash_cnt+1,x)-b;}struct Q{    int A,B,K;}q[N];int Root[N],mp[N];struct bit_seg{    int add[60],mns[60],cnt1,cnt2;    int root[N];    inline int lowbit(int x){        return x&-x;    }    inline void insert(int num,int &now,int l,int r,int val){        t[++tot]=t[now];        now=tot;        t[now].size+=val;        if(l==r)return;        int mid=(l+r)>>1;        if(num<=mid)insert(num,t[now].ls,l,mid,val);        else insert(num,t[now].rs,mid+1,r,val);    }    //我这里用的二分,卡rank榜    inline int query(int L,int R,int k){        int l=L,r=R;        while(l<r){            int rsize=0;            for(int i=1;i<=cnt1;i++)rsize+=t[t[add[i]].rs].size;            for(int i=1;i<=cnt2;i++)rsize-=t[t[mns[i]].rs].size;            int mid=(l+r)>>1;            if(k>rsize){                for(int i=1;i<=cnt1;i++)add[i]=t[add[i]].ls;                for(int i=1;i<=cnt2;i++)mns[i]=t[mns[i]].ls;                return query(l,mid,k-rsize);            }            else{                for(int i=1;i<=cnt1;i++)add[i]=t[add[i]].rs;                for(int i=1;i<=cnt2;i++)mns[i]=t[mns[i]].rs;                return query(mid+1,r,k);            }        }        int size=0;        for(int i=1;i<=cnt1;i++)size+=t[add[i]].size;        for(int i=1;i<=cnt2;i++)size-=t[mns[i]].size;        if(k>size)return -1;        else return b[l];    }    inline int Query(int A,int B,int C,int D,int k){        cnt1=cnt2=0;        mns[++cnt2]=Root[A];mns[++cnt2]=Root[B];        add[++cnt1]=Root[C];add[++cnt1]=Root[D];        for(int i=mp[A];i;i-=lowbit(i))mns[++cnt2]=root[i];        for(int i=mp[B];i;i-=lowbit(i))mns[++cnt2]=root[i];        for(int i=mp[C];i;i-=lowbit(i))add[++cnt1]=root[i];        for(int i=mp[D];i;i-=lowbit(i))add[++cnt1]=root[i];        return query(1,hash_cnt,k);    }    inline void Insert(int pos,int x,int val){        for(int i=pos;i<=n;i+=lowbit(i)){            insert(x,root[i],1,hash_cnt,val);        }    }}tree;struct edge{    int to,next;}e[N<<1];int head[N];inline void addedge(int x,int y){    e[++cnt].to=y;e[cnt].next=head[x];head[x]=cnt;}int st[17][N],size[N],dep[N];inline void dfs(int x,int fa){    dep[x]=dep[fa]+1;    size[x]=1;    st[0][x]=fa;    a[++dfn_clock]=v[x];    mp[x]=dfn_clock;    for(int k=1;k<=16;k++){        st[k][x]=st[k-1][st[k-1][x]];    }    Root[x]=Root[fa];    tree.insert(v[x],Root[x],1,hash_cnt,1);    for(int i=head[x];i;i=e[i].next){        int u=e[i].to;        if(u==fa)continue;        dfs(u,x);        size[x]+=size[u];    }}inline int getlca(int x,int y){    if(x==y)return x;    if(dep[x]>dep[y])swap(x,y);    for(int k=16;k>=0;k--){        if(dep[st[k][y]]>=dep[x]){            y=st[k][y];        }    }    if(x==y)return x;    for(int k=16;k>=0;k--){        if(st[k][x]!=st[k][y]){            x=st[k][x];            y=st[k][y];        }    }    return st[0][x];}int main(){    n=read();m=read();    for(int i=1;i<=n;i++){        v[i]=read();b[++hash_cnt]=v[i];    }    for(int i=1;i<=n-1;i++){        int x=read(),y=read();        addedge(x,y);addedge(y,x);    }    for(int i=1;i<=m;i++){        q[i].K=read();        if(q[i].K){            q[i].A=read();q[i].B=read();        }        else{            q[i].A=read();q[i].B=read();b[++hash_cnt]=q[i].B;        }    }    sort(b+1,b+hash_cnt+1);    hash_cnt=unique(b+1,b+hash_cnt+1)-b-1;    for(int i=1;i<=n;i++){        v[i]=Hash(v[i]);    }    dfs(1,0);    for(int i=1;i<=m;i++){        if(q[i].K==0){            int x=q[i].A;            tree.Insert(mp[x],a[mp[x]],-1);            tree.Insert(mp[x]+size[x],a[mp[x]],1);            int val=Hash(q[i].B);a[mp[x]]=val;            tree.Insert(mp[x],val,1);            tree.Insert(mp[x]+size[x],val,-1);        }        else{            int lca=getlca(q[i].A,q[i].B);            int A=lca,B=st[0][lca],C=q[i].A,D=q[i].B;            int ans=tree.Query(A,B,C,D,q[i].K);            if(ans==-1)printf("invalid request!\n");            else printf("%d\n",ans);        }    }    return 0;}
阅读全文
0 0
原创粉丝点击