zoukankan      html  css  js  c++  java
  • bzoj 4129: Haruna’s Breakfast

    4129: Haruna’s Breakfast

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 997  Solved: 471
    [Submit][Status][Discuss]

    Description

     Haruna每天都会给提督做早餐! 这天她发现早饭的食材被调皮的 Shimakaze放到了一棵

    树上,每个结点都有一样食材,Shimakaze要考验一下她。
    每个食材都有一个美味度,Shimakaze会进行两种操作:
    1、修改某个结点的食材的美味度。
    2、对于某条链,询问这条链的美味度集合中,最小的未出现的自然数是多少。即mex值。
    请你帮帮Haruna吧。
     

    Input

    第一行包括两个整数n,m,代表树上的结点数(标号为1~n)和操作数。

    第二行包括n个整数a1...an,代表每个结点的食材初始的美味度。
    接下来n-1行,每行包括两个整数u,v,代表树上的一条边。
    接下来m 行,每行包括三个整数
    0 u x 代表将结点u的食材的美味度修改为 x。
    1 u v 代表询问以u,v 为端点的链的mex值。
     

    Output

    对于每次询问,输出该链的mex值。

     

    Sample Input

    10 10
    1 0 1 0 2 4 4 0 1 0
    1 2
    2 3
    2 4
    2 5
    1 6
    6 7
    2 8
    3 9
    9 10
    0 7 14
    1 6 6
    0 4 9
    1 2 2
    1 1 8
    1 8 3
    0 10 9
    1 3 5
    0 10 0
    0 7 7

    Sample Output

    0
    1
    2
    2
    3

    HINT

    1<=n<=5*10^4


    1<=m<=5*10^4

    0<=ai<=10^9
    #include <bits/stdc++.h>
    #define ll long long
    #define pii pair<int,int>
    const int MAXN=5e4+10;
    const int inf=5e4+5;
    using namespace std;
    ll readll(){
        ll 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;
    }
    int readint(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return f*x;
    }
    int n,m,size,p[MAXN<<1],c[MAXN];
    ll a[MAXN];pii Next[MAXN<<1],to[MAXN],past[MAXN];
    int first[MAXN],cnt1,size1;
    void add(int u,int v){
    	Next[++cnt1].first=first[u];Next[cnt1].second=v;first[u]=cnt1;
    	Next[++cnt1].first=first[v];Next[cnt1].second=u;first[v]=cnt1;
    }
    int b[MAXN<<1],begin[MAXN],last[MAXN],cnt,num[MAXN],son[MAXN],fa[MAXN],dep[MAXN];
    void dfs1(int v,int pre,int deep){
    	b[++cnt]=v;begin[v]=cnt;num[v]=1;dep[v]=deep+1;fa[v]=pre;
    	for(int i=first[v];i!=-1;i=Next[i].first){
    		int u=Next[i].second;
    		if(u!=pre){
    			dfs1(u,v,deep+1);
    			num[v]+=num[u];
    			if(son[v]==-1||num[son[v]]<num[u]) son[v]=u;
    		}
    	}
    	b[++cnt]=v;last[v]=cnt;
    }
    int tp[MAXN];
    void dfs2(int v,int td){
    	tp[v]=td;
    	if(son[v]!=-1) dfs2(son[v],td);
    	for(int i=first[v];i!=-1;i=Next[i].first){
    		int u=Next[i].second;
    		if(u!=fa[v]&&u!=son[v]) dfs2(u,u);
    	}
    }
    int Lca(int u,int v){
    	int uu=tp[u];int vv=tp[v];
    	while(uu!=vv){
    		if(dep[uu]<dep[vv]){
    			swap(uu,vv);swap(u,v);
    		}
    		u=fa[uu];uu=tp[u];
    	}
    	if(dep[u]>dep[v]) swap(u,v);
    	return u;
    }
    typedef struct node{
    	int l,r,t,biao,lca,flag;
    	friend bool operator <(node aa,node bb){
    		if(p[aa.l]==p[bb.l]&&p[aa.r]==p[bb.r]) return aa.t<bb.t;
    		else if(p[aa.l]==p[bb.l]) return p[aa.r]<p[bb.r];
    		else return p[aa.l]<p[bb.l];
    	}
    }node;
    node d[MAXN];int kuai[1005];int cont[inf],pp[inf],vis[MAXN];
    void update(int l,int r,int t){
    	int u=to[t].first;int vul=to[t].second;
    	int t1=begin[u];int t2=last[u];int cp=0;int pos;
    	if(t1>=l&&t1<=r) cp++,pos=t1;
    	if(t2>=l&&t2<=r) cp++,pos=t2;
    	if(cp==1){
    		if(vul+1<inf){
    			if(a[b[pos]]+1<inf){
    				cont[a[b[pos]]+1]--;
    				if(!cont[a[b[pos]]+1]) kuai[pp[a[b[pos]]+1]]--;
    			}
    			cont[vul+1]++;
    			if(cont[vul+1]==1) kuai[pp[vul+1]]++;
    		}
    	}
    	a[u]=vul;
    }
    void restore(int l,int r,int t){
    	int u=past[t].first;int vul=past[t].second;
    	int t1=begin[u];int t2=last[u];int cp=0;int pos;
    	if(t1>=l&&t1<=r) cp++,pos=t1;
    	if(t2>=l&&t2<=r) cp++,pos=t2;
    	if(cp==1){
    		if(vul+1<inf){
    			if(a[b[pos]+1]<inf){
    				cont[a[b[pos]]+1]--;
    				if(!cont[a[b[pos]]+1]) kuai[pp[a[b[pos]]+1]]--;
    			}
    			cont[vul+1]++;
    			if(cont[vul+1]==1) kuai[pp[vul+1]]++;
    		}
    	}
    	a[u]=vul;
    }
    void work(int pos){
    	vis[b[pos]]^=1;
    	if(vis[b[pos]]){
    		if(a[b[pos]]+1<inf){
    			cont[a[b[pos]]+1]++;
    			if(cont[a[b[pos]]+1]==1) kuai[pp[a[b[pos]]+1]]++;
    		}
    	}
    	else{
    		if(a[b[pos]]+1<inf){
    			cont[a[b[pos]]+1]--;
    			if(!cont[a[b[pos]]+1]) kuai[pp[a[b[pos]]+1]]--;
    		}
    	}
    }
    int querty(){
    	for(int i=1;i<pp[inf-1];i++){
    		if(kuai[i]==size1) continue;
    		for(int j=(i-1)*size1+1;j<=i*size1;j++){
    			if(!cont[j]) return j;
    		}
    	}
    	for(int i=(pp[inf-1]-1)*size1+1;i<inf;i++){
    		if(!cont[i]) return i;
    	}
    }
    int ans[MAXN];
    void print(){
    	cout<<"======="<<endl;
    	for(int i=1;i<=pp[inf-1];i++){
    		if(!kuai[i]) break;
    		printf("%d ",kuai[i]);
    	}
    	cout<<endl;
    }
    int main(){
    	ios::sync_with_stdio(false);
    	n=readint();m=readint();size=(int)pow(n*2,2.0/3);
    	size1=(int)sqrt(inf-1);
    	for(int i=1;i<=2*n;i++) p[i]=(i-1)/size+1;
    	for(int i=1;i<inf;i++) pp[i]=(i-1)/size1+1;
    	for(int i=1;i<=n;i++) son[i]=first[i]=-1;
    	for(int i=1;i<=n;i++) c[i]=a[i]=readll();
    	int u,v,l,r,op;ll x;
    	for(int i=1;i<n;i++) u=readint(),v=readint(),add(u,v);
    	dfs1(1,-1,0);dfs2(1,1);int T=0;int uu=0;
    //	for(int i=1;i<=2*n;i++) cout<<b[i]<<" ";
    //	cout<<endl;
    	for(int i=1;i<=m;i++){
    		op=readint();
    		if(op==0){
    			l=readint();x=readll();
    			to[++T].first=l;to[T].second=x;
    			past[T].first=l;past[T].second=c[l];
    			c[l]=x;
    		}
    		else{
    			l=readint();r=readint();d[++uu].biao=uu;d[uu].lca=Lca(l,r);d[uu].t=T;
    			if(d[uu].lca==l||d[uu].lca==r) d[uu].l=min(begin[l],begin[r]),d[uu].r=max(begin[l],begin[r]);
    			else{
    				if(begin[l]>begin[r]) swap(l,r);
    				d[uu].l=last[l];d[uu].r=begin[r];d[uu].flag=1;
    			}
    		}
    	}
    	sort(d+1,d+uu+1);
    //	for(int i=1;i<=uu;i++) cout<<d[i].l<<" "<<d[i].r<<" "<<d[i].biao<<" "<<d[i].t<<" "<<d[i].lca<<endl;
    	int L=1,R=0;T=0;
    	for(int i=1;i<=uu;i++){
    		while(T>d[i].t){
    			restore(L,R,T);T--;
    		}
    		while(T<d[i].t){
    			T++;update(L,R,T);
    		}
    		while(R>d[i].r){
    			work(R);R--;
    		}
    		while(R<d[i].r){
    			R++;work(R);
    		}
    		while(L<d[i].l){
    			work(L);L++;
    		}
    		while(L>d[i].l){
    			L--;work(L);
    		}
    		if(d[i].flag&&a[d[i].lca]+1<inf){
    			cont[a[d[i].lca]+1]++;
    			if(cont[a[d[i].lca]+1]==1) kuai[pp[a[d[i].lca]+1]]++;
    		}
    		ans[d[i].biao]=querty();
    		if(d[i].flag&&a[d[i].lca]+1<inf){
    			cont[a[d[i].lca]+1]--;
    			if(!cont[a[d[i].lca]+1]) kuai[pp[a[d[i].lca]+1]]--;
    		}
    	//	print();
    	}
    	for(int i=1;i<=uu;i++) printf("%d
    ",ans[i]-1);
    	return 0;
    }
    

      

  • 相关阅读:
    LALR(1)语法分析生成器--xbytes
    <<摩托车修理技术与禅>>读书笔记
    xscript脚本
    CentOS安装Erlang
    TCP中close和shutdown之间的区别
    Erlang高阶函数
    深度学习小记
    mac平台打造犀利的Android Studio开发环境
    MAC中如何配置两套android-sdk环境
    Ubuntu虚拟机编译Android6.0总结
  • 原文地址:https://www.cnblogs.com/wang9897/p/8457719.html
Copyright © 2011-2022 走看看