codeforces 600E 线段树合并
发布时间:2020-12-16 09:19:00 所属栏目:百科 来源:网络整理
导读:题意:给你一棵有? n n?个点的树? (nleq10^5) ( n ≤ 1 0 5 )?,树上每个节点都有一种颜色? ci(cileq n) c i ( c i ≤ n )?,让你求每个点子树出现最多的颜色的 颜色编号 的和 ? 权值线段维护一下出现最多的数字即可 #includebits/stdc++.h using namespac
题意:给你一棵有?nn?个点的树?(nleq10^5)(n≤105)?,树上每个节点都有一种颜色?ci(cileq n)ci(ci≤n)?,让你求每个点子树出现最多的颜色的 颜色编号 的和 ? 权值线段维护一下出现最多的数字即可 #include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,b) for(int i=(a);i>=(b);--i) #define ll long long #define see(x) (cerr<<(#x)<<‘=‘<<(x)<<endl) #define inf 0x3f3f3f3f #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// const int N=2e6+10; ll sum[N<<2],t[N<<2],anss[N]; int lson[N<<2],rson[N<<2],ncnt,pos,head[N],c[N],n,T[N]; void up(int pos) { if(sum[lson[pos]]>sum[rson[pos]]) { sum[pos]=sum[lson[pos]]; t[pos]=t[lson[pos]]; } else if(sum[lson[pos]]<sum[rson[pos]]) { sum[pos]=sum[rson[pos]]; t[pos]=t[rson[pos]]; } else if(sum[lson[pos]]==sum[rson[pos]]) { sum[pos]=sum[lson[pos]]; t[pos]=t[lson[pos]]+t[rson[pos]]; } } void upnode(int x,int l,int r,int &pos) { if(!pos)pos=++ncnt; if(l==r){sum[pos]+=1;t[pos]=l;return ;} int m=(l+r)>>1; if(x<=m)upnode(x,l,m,lson[pos]); else upnode(x,m+1,r,rson[pos]); up(pos); } int Merge(int a,int b,int r) { if(!a)return b; if(!b)return a; if(l==r) { sum[a]+=sum[b]; t[a]=l; return a; } int m=(l+r)>>1; lson[a]=Merge(lson[a],lson[b],m); rson[a]=Merge(rson[a],rson[b],r); up(a);return a; } struct Edge{int to,nex;}edge[N]; void add(int a,int b){edge[++pos]=(Edge){b,head[a]};head[a]=pos;} void dfs(int x,int fa) { for(int i=head[x];i;i=edge[i].nex) { int v=edge[i].to; if(v==fa)continue; dfs(v,x);//注意 这里是 先更新 然后再合并 Merge(T[x],T[v],1,1e5); } upnode(c[x],1,100000,T[x]); anss[x]=t[T[x]]; } int main() { cin>>n; rep(i,n)scanf("%d",&c[i]),ncnt++,T[i]=i; rep(i,n-1) { int x,y;scanf("%d%d",&x,&y); add(x,y);add(y,x); } dfs(1,0); rep(i,1,n) printf("%lld ",anss[i]); return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |