CSU1811-Tree Intersection
来源:互联网 发布:宁波行知实验小学网站 编辑:程序博客网 时间:2024/06/05 11:43
Tree Intersection
Time Limit: 1 Sec Memory Limit: 128 Mb Submitted: 498 Solved: 176Description
Bobo has a tree with n vertices numbered by1,2,…,n and (n-1) edges. The i-th vertex has color c i, and the i-th edgeconnects vertices a i and b i.Let C(x,y) denotes the set of colors insubtree rooted at vertex x deleting edge (x,y).Bobo would like to know R_i which is thesize of intersection of C(a i,b i) and C(b i,a i) for all 1≤i≤(n-1). (i.e. |C(ai,b i)∩C(b i,a i)|)
Input
The input contains at most 15 sets. Foreach set:
The first line contains an integer n(2≤n≤10 5).
The second line contains n integers c 1,c2,…,c n (1≤c_i≤n).
The i-th of the last (n-1) lines contains 2integers a i,b i (1≤a i,b i≤n).
Output
For each set, (n-1) integers R 1,R 2,…,R n-1.
Sample Input
41 2 2 11 22 33 451 1 2 1 21 32 33 54 5
Sample Output
1211121
题意:给你一棵树,对于每条边,把这条边删了,树分成了两个集合,求这两个集合中共同的颜色数量
解题思路:莫队或线段树启发式合并,关键都是看一个集合是否达到一种颜色的总量
线段树启发式合并:
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <map>#include <cmath>#include <set>#include <stack>#include <queue>#include <vector>#include <bitset>#include <functional>using namespace std;#define LL long longconst int INF = 0x3f3f3f3f;int n,x,y,a[100009],ans[100009],cnt[100009];int s[100009],nt[200009],e[200009],v[200009],res;int ss[100009],L[4000009],R[4000009],f[4000009],g[4000009],tot;void make(int &k,int l,int r,int p){ k=++tot,L[k]=R[k]=0; if(l==r) {g[k]=1,f[k]=g[k]%cnt[p];return ;} int mid=(l+r)>>1; if(p<=mid) make(L[k],l,mid,p); else make(R[k],mid+1,r,p); f[k]=f[L[k]]+f[R[k]];}void Merge(int &now,int pre,int l,int r){ if(!now||!pre) {now=now^pre;return ;} if(l==r) {f[now]=(bool)(g[now]=(g[now]+g[pre])%cnt[l]);return ;} int mid=(l+r)>>1; Merge(L[now],L[pre],l,mid); Merge(R[now],R[pre],mid+1,r); f[now]=f[L[now]]+f[R[now]];}void dfs(int k,int fa){ make(ss[k],1,n,a[k]); for(int i=s[k];~i;i=nt[i]) { if(e[i]==fa) continue; dfs(e[i],k); ans[v[i]]=f[ss[e[i]]]; Merge(ss[k],ss[e[i]],1,n); }}int main(){while(~scanf("%d",&n)) { memset(s,-1,sizeof s); memset(cnt,0,sizeof cnt); tot=L[0]=R[0]=res=0; for(int i=1;i<=n;i++) scanf("%d",&a[i]),cnt[a[i]]++; for(int i=1;i<n;i++) { scanf("%d%d",&x,&y); nt[res]=s[x],s[x]=res,e[res]=y,v[res++]=i; nt[res]=s[y],s[y]=res,e[res]=x,v[res++]=i; } dfs(1,0); for(int i=1;i<n;i++) printf("%d\n",ans[i]); }return 0;}
莫队:
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <map>#include <cmath>#include <set>#include <stack>#include <queue>#include <vector>#include <bitset>#include <functional>using namespace std;#define LL long longconst int INF = 0x3f3f3f3f;int s[100010],nt[200010],e[200010],flag[200010],id[200010];int n,u,v,res,N;int w[100010],cnt[100010],sum[100010];int x[100010],L[100010],R[100010];struct node{ int L,R,id;} q[100010];int ans[100010],ans1,ans2;void dfs(int k,int fa){ x[++res]=w[k]; L[k]=res; for(int i=s[k]; ~i; i=nt[i]) { if(e[i]==fa) continue; flag[i]=1; dfs(e[i],k); } R[k]=res;}bool cmp(node a,node b){ if(a.L/N==b.L/N) return a.R<b.R; return a.L/N<b.L/N;}void check1(int k){ if(cnt[x[k]]-sum[x[k]]==1) ans1--; if(sum[x[k]]==0) ans2--;}void check2(int k){ if(sum[x[k]]==cnt[x[k]]) ans1++; if(sum[x[k]]==1) ans2++;}int main(){ while(~scanf("%d",&n)) { memset(cnt,0,sizeof cnt); memset(s,-1,sizeof s); memset(sum,0,sizeof sum); for(int i=1; i<=n; i++) scanf("%d",&w[i]),cnt[w[i]]++; res=0; for(int i=1; i<n; i++) { scanf("%d%d",&u,&v); nt[res]=s[u],s[u]=res,e[res]=v,id[res]=i,flag[res++]=0; nt[res]=s[v],s[v]=res,e[res]=u,id[res]=i,flag[res++]=0; } res=0; dfs(1,-1); res=0; for(int i=1; i<=n; i++) { for(int j=s[i]; ~j; j=nt[j]) { if(!flag[j]) continue; q[res].L=L[e[j]]; q[res].R=R[e[j]]; q[res++].id=id[j]; } } N=sqrt(n); sort(q,q+n-1,cmp); ans1=0,ans2=0; int ll=1,rr=0; for(int i=0; i<n-1; i++) { while(ll<q[i].L) sum[x[ll]]--,check1(ll),ll++; while(ll>q[i].L) ll--,sum[x[ll]]++,check2(ll); while(rr>q[i].R) sum[x[rr]]--,check1(rr),rr--; while(rr<q[i].R) rr++,sum[x[rr]]++,check2(rr); ans[q[i].id]=ans2-ans1; } for(int i=1; i<n; i++) printf("%d\n",ans[i]); } return 0;}
- [dsu] CSU1811: Tree Intersection
- CSU1811-Tree Intersection
- 线段树合并 csu1811 Tree Intersection
- csu1811 Tree Intersection(线段树合并)★ ★ ★
- CSU 1811 Tree Intersection
- CSU 1811 Tree Intersection
- 1811: Tree Intersection
- AIZU 1001 Binary Tree Intersection And Union
- CSU 1811 Tree Intersection(启发式合并)
- CSU 1811 Tree Intersection(启发式合并)
- CSU 1811 Tree Intersection(莫队算法)
- Intersection
- Intersection
- Intersection
- Intersection
- CSU 1811 Tree Intersection(dfs序+莫队算法)
- csu 1811 Tree Intersection 2016湖南省赛 I
- CSU 1811 Tree Intersection 平衡树启发式合并
- post请求上传文件和文本时http格式
- Linux基础入门(六) --学习笔记-正则表达式
- 浅谈opencv中的Mat在处理图像数据中的用法
- 153. Find Minimum in Rotated Sorted Array
- 对接钉钉接口可能遇到的问题 50004 60011
- CSU1811-Tree Intersection
- javaweb图书管理系统
- Java编译后产生class文件的命名规则
- C语言 java 判断一个数是不是质数
- 作业1
- 【C++ 异常】error: jump to case label, crosses initialization
- SpringCloud(第 023 篇)简单文件上传微服务采取curl或者页面点击实现文件上传
- Spring 学习(四) AOP
- 第三周第二节(第二章——线性表2)