zoukankan      html  css  js  c++  java
  • jzoj5989. 【北大2019冬令营模拟2019.1.6】Forest (set)

    题面

    题解

    为了一点小细节卡了一个下午……我都怕我瞎用set把电脑搞炸……

    观察一次(1)操作会造成什么影响,比如说把(A[i])(x)改成(y)

    (D[x])(-1),导致(E[x]=B[x]/D[x])会修改

    (D[y])(+1),导致(E[y]=B[y]/D[y])会修改

    连边关系会修改

    当某个(E[x])改变时,所有跟它距离不超过(1)的点的(C[])值都要修改

    (C[A[x]]):单点修改

    (C[x]):单点修改

    儿子们的(C[]):打个标记

    那么思路就明确了:对每个点搞个(set)维护它的儿子

    修改单点的时候从父亲的(set)里拿出来,修改掉再插回去

    对儿子整体修改的时候打标记

    在全局再开两个(set),分别维护所有(set)最小值的最小值、最大值的最大值

    断开/连接一条边的时候把标记的贡献算一下

    以上是官方题解,这里说几个细节:

    因为对于儿子们的(C_i),是所有的儿子和父亲的(E_i)之和加上一堆乱七八糟的东西,所以算儿子的(C_i)时可以不加上父亲的(E_i),等需要答案的时候再加上去,这样修改的时候可以直接更新父亲的(E_i)即可

    最后,注意细节

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define ll long long
    #define IT multiset<ll>::iterator
    #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
    #define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    ll read(){
        R ll res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    char sr[1<<21],z[20];int C=-1,Z=0;
    inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    void print(R ll x){
        if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
        while(z[++Z]=x%10+48,x/=10);
        while(sr[++C]=z[Z],--Z);sr[++C]='
    ';
    }
    const int N=1e5+5;
    ll b[N],c[N],e[N];int to[N],d[N],n,m,op,x,y;
    multiset<ll>s[N],mn,mx;IT it;
    void update(int x,ll vva,ll val,int ty){
    	if(!s[x].empty()){
    		it=mn.lower_bound((*s[x].begin())+e[x]),mn.erase(it);
    		it=mx.lower_bound((*--s[x].end())+e[x]),mx.erase(it);
    	}
    //		printf("%d
    ",m);
    	if(ty==-1)it=s[x].lower_bound(vva),s[x].erase(it);
    	it=mn.lower_bound((*s[to[x]].begin())+e[to[x]]),mn.erase(it);
    	it=mx.lower_bound((*--s[to[x]].end())+e[to[x]]),mx.erase(it);
    	it=mn.lower_bound((*s[to[to[x]]].begin())+e[to[to[x]]]),mn.erase(it);
    	it=mx.lower_bound((*--s[to[to[x]]].end())+e[to[to[x]]]),mx.erase(it);
    	
    	it=s[to[x]].lower_bound(c[x]),s[to[x]].erase(it);
    	it=s[to[to[x]]].lower_bound(c[to[x]]),s[to[to[x]]].erase(it);
    	
    	c[to[x]]-=e[x],c[x]-=b[x]-d[x]*e[x]+e[x],d[x]+=ty;
    	e[x]=b[x]/d[x],c[x]+=b[x]-d[x]*e[x]+e[x],c[x]+=ty*val,c[to[x]]+=e[x];
    	
    	if(ty==1)s[x].insert(vva);
    	s[to[x]].insert(c[x]),s[to[to[x]]].insert(c[to[x]]);
    	mn.insert((*s[to[x]].begin())+e[to[x]]);
    	mx.insert((*--s[to[x]].end())+e[to[x]]);
    	mn.insert((*s[to[to[x]]].begin())+e[to[to[x]]]);
    	mx.insert((*--s[to[to[x]]].end())+e[to[to[x]]]);
    	
    	if(!s[x].empty()){
    		mn.insert((*s[x].begin())+e[x]);
    		mx.insert((*--s[x].end())+e[x]);
    	}
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    //	freopen("testdata.out","w",stdout);
    	freopen("forest.in","r",stdin);
    	freopen("forest.out","w",stdout);
    	n=read(),m=read();
    	fp(i,1,n)b[i]=read(),++d[i];
    	fp(i,1,n)to[i]=read(),++d[i],++d[to[i]];
    	fp(i,1,n)e[i]=b[i]/d[i],c[i]=b[i]-d[i]*e[i]+e[i];
    	fp(i,1,n)c[to[i]]+=e[i];
    	fp(i,1,n)s[to[i]].insert(c[i]);
    	fp(i,1,n)if(!s[i].empty()){
    		mn.insert((*s[i].begin())+e[i]);
    		mx.insert((*--s[i].end())+e[i]);
    	}
    	while(m--){
    		op=read();
    		switch(op){
    			case 1:{
    				x=read(),y=read();if(to[x]==y)continue;
    				update(to[x],c[x],e[x],-1);
    				to[x]=y;
    				update(to[x],c[x],e[x],1);
    				break;
    			}
    			case 2:x=read(),print(c[x]+e[to[x]]);break;
    			case 3:print(*mn.begin()),sr[C]=' ',print(*--mx.end());break;
    		}
    	}return Ot(),0;
    }
    
  • 相关阅读:
    oracle 导入数据时提示只有 DBA 才能导入由其他 DBA 导出的文件
    oracle 常用语句
    android udp 无法收到数据 (模拟器中)
    android DatagramSocket send 发送数据出错
    AtCoder ABC 128E Roadwork
    AtCoder ABC 128D equeue
    AtCoder ABC 127F Absolute Minima
    AtCoder ABC 127E Cell Distance
    CodeForces 1166E The LCMs Must be Large
    CodeForces 1166D Cute Sequences
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10229481.html
Copyright © 2011-2022 走看看