标签:sam amp its 编号 inline 模拟 namespace stream store
雨天的尾巴
深绘里一直很讨厌雨天。
灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切。
虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒了几座老房子,几棵老树被连根拔起,以及田地里的粮食被弄得一片狼藉。
无奈的深绘里和村民们只好等待救济粮来维生。
不过救济粮的发放方式很特别。
首先村落里的一共有n 座房屋,并形成一个树状结构。然后救济粮分m 次发放,每次选择两个房屋(x,y),然后对于x 到y 的路径上(含x 和y) 每座房子里发放一袋z 类型的救济粮。
然后深绘里想知道,当所有的救济粮发放完毕后,每座房子里存放的最多的是哪种救济粮。
5 3 1 2 3 1 3 4 5 4 2 3 3 1 5 2 3 3 3
2 3 3 0 2
1 #include<cstdio>
2 #include<iostream>
3 using namespace std;
4 const int N=100005;
5 const int M=20000005;
6 int Head[N],Next[N*2],V[N*2],cnt=0;//store the tree structure before DFS
7 int Ans[N],ST[N][17],dep[N],F[N];//store the DP data for ST to get LCA
8 int lch[M],rch[M],size,key[M];//store the inner tree----key[] records the maximum of the food.same.count()
9 int Hash[N],n;//z can be as big as 10^9 so hash can condense it to an acceptable range
10 inline void Link(int x,int y)
11 {
12 cnt++;
13 V[cnt]=y;
14 Next[cnt]=Head[x];
15 Head[x]=cnt;
16 }
17 inline void Dfs(int x,int f,int D)
18 {
19 dep[x]=D;
20 F[x]=f;
21 ST[x][0]=f;
22 for(int i=1;i<=16;i++)
23 {
24 if(dep[x]-(1<<i)>=1) ST[x][i]=ST[ST[x][i-1]][i-1];
25 else break;
26 }
27 for(int i=Head[x];i;i=Next[i]) if(V[i]!=f) Dfs(V[i],x,D+1);
28 }
29 inline int LCA(int x,int y)
30 {
31 if(dep[x]>dep[y])
32 {
33 for(int i=16;i>=0;i--) if(dep[ST[x][i]]>=dep[y]) x=ST[x][i];
34 }
35 else if(dep[y]>dep[x])
36 {
37 for(int i=16;i>=0;i--) if(dep[ST[y][i]]>=dep[x]) y=ST[y][i];
38 }//move x and y to the same depth
39 if(x==y) return x;
40 for(int i=16;i>=0;i--)
41 {
42 if(ST[y][i]!=ST[x][i])
43 {
44 y=ST[y][i];
45 x=ST[x][i];
46 }
47 }
48 return F[x];
49 }
50 inline int Find_Space(int x)
51 {
52 int p=x%N;
53 while(Hash[p]!=x&&Hash[p]!=0)
54 {
55 p++;
56 if(p==N) p=0;
57 }
58 if(!Hash[p]) Hash[p]=x;
59 return p;
60 }
61 inline void Insert(int &x,int l,int r,int num,int k)
62 {
63 if(x==0) x=++size;
64 if(l==r)
65 {
66 key[x]+=k;
67 return;
68 }
69 int mid=(l+r)>>1;
70 if(num<=mid) Insert(lch[x],l,mid,num,k);
71 else Insert(rch[x],mid+1,r,num,k);
72 key[x]=max(key[lch[x]],key[rch[x]]);
73 }
74 inline void Merge(int p,int fp,int l,int r)
75 {
76 if(l==r)
77 {
78 key[fp]+=key[p];
79 return;
80 }
81 int mid=(l+r)>>1;
82 if(lch[p])
83 {
84 if(!lch[fp]) lch[fp]=lch[p];
85 else Merge(lch[p],lch[fp],l,mid);
86 }
87 if(rch[p])
88 {
89 if(!rch[fp]) rch[fp]=rch[p];
90 else Merge(rch[p],rch[fp],mid+1,r);
91 }
92 key[fp]=max(key[lch[fp]],key[rch[fp]]);
93 }
94 inline int Query(int p,int l,int r)
95 {
96 if(!p) return 0;
97 if(l==r) return l;
98 int mid=(l+r)>>1;
99 if(key[lch[p]]>=key[rch[p]])
100 {
101 if(key[lch[p]]>0) return Query(lch[p],l,mid);
102 else return 0;
103 }
104 else
105 {
106 if(key[rch[p]]>0) return Query(rch[p],mid+1,r);
107 else return 0;
108 }
109 }
110 inline void Reply(int x)
111 {
112 for(int i=Head[x];i;i=Next[i]) if(V[i]!=F[x])
113 {
114 Reply(V[i]);
115 Merge(V[i],x,1,N);//merge the zone tree to its outer father‘s zone tree
116 }
117 Ans[x]=Query(x,1,N);
118 }
119 int main()
120 {
121 int m,x,y,z,anc;
122 scanf("%d%d",&n,&m);
123 size=n*2;
124 for(int i=1;i<n;i++)
125 {
126 scanf("%d%d",&x,&y);
127 Link(x,y);
128 Link(y,x);
129 }
130 Dfs(1,0,1);
131 while(m--)
132 {
133 scanf("%d%d%d",&x,&y,&z);
134 z=Find_Space(z);
135 anc=LCA(x,y);
136 Insert(x,1,N,z,1);
137 Insert(y,1,N,z,1);
138 Insert(anc,1,N,z,-1);
139 if(F[anc]) Insert(F[anc],1,N,z,-1);
140 }
141 Reply(1);
142 for(int i=1;i<=n;i++) printf("%d\n",Hash[Ans[i]]);
143 return 0;
144 }
标签:sam amp its 编号 inline 模拟 namespace stream store
原文地址:http://www.cnblogs.com/801234567com/p/6900688.html