Rain tail

When the examination is directly tied to the first question this question did not even break out T_T violence;

Mentality:

At that time thought of discrete (very nervous did not break out ...), a tree difference, lca doubled, then doubled feel drops of difficult to play, a look n <100000, then choose

Up by labeling, but less critical zero line of code ,,,, two lines of tears. . .

It now appears that doubling is really not very difficult ah good fight there is easy to use, it is difficult not to have emotions, just finished.

The reason why the merger did not expect the tree line because there was not really a thorough understanding of, so sum up the discovery of new knowledge or to know that it can do, know its advantages. . .

}

Discrete time to kill 1-> 10 ^ 9, the examination of really stupid think if there is 10 ^ 9 kinds not to play it and found that there ,,, m operations this stuff, so the z discrete len the maximum card out there is a lot of m

So we have to do off-line (I admit now know that online is offline Well stuff .. shame ah ...)

Each point has a lot of information so the tree line weights to optimize the space (of course, can optimize the time), dynamic open tree insertion and deletion (lca, f [lca]) for each point, finally dfs, father merger son.

Therefore maxcnt requiring maintenance interval and its id, when the multi-pass merge would require about l, r (1, len), if the value l == r and maxx update id, be noted that if maxx <= 0, id dry to 0 (subject requirements).

sd error: I forgot to merge plus root [x] = merge, if the root [x] = 0, it will ... explode. There did not open enough to get a space open to maxn * 50.

Optimization: When you insert if lca == x || lca == y, then insert a deleted once why they are not inserted. . .

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; const int maxn=100050; bool mark[maxn]; int n,m,t,ans[maxn],len; int kpx[maxn],kpy[maxn],kpz[maxn],turn[maxn];//离线离散化 int deep[maxn],f[maxn][20];//倍增lca int sz,root[maxn],cnt[maxn*50],lc[maxn*50],rc[maxn*50],maxx[maxn*50],num[maxn*50];//线段树 int head[maxn],cntn=1; struct node{ int to,next; }line[maxn*2]; void add(int x,int y) { line[cntn].to=y; line[cntn].next=head[x]; head[x]=cntn++; } void dfs(int x) { for(int i=head[x];i;i=line[i].next) { int v=line[i].to; if(!mark[v]) { mark[v]=1; deep[v]=deep[x]+1; f[v][0]=x; for(int j=1;j<=t;j++) f[v][j]=f[f[v][j-1]][j-1]; dfs(v); } } } int ask(int x,int y) { if(deep[x]>deep[y]) swap(x,y); for(int j=t;j>=0;j--) if(deep[f[y][j]]>=deep[x]) y=f[y][j]; if(x==y) return x; for(int j=t;j>=0;j--) { if(f[x][j]!=f[y][j]) { x=f[x][j]; y=f[y][j]; } } return f[x][0]; } void insert(int &root,int l,int r,int x) { if(!root) root=++sz; cnt[root]++; if(l==r) { maxx[root]=cnt[root]; num[root]=maxx[root]<=0?0:l; return; } int mid=(l+r)/2; if(x<=mid) insert(lc[root],l,mid,x); else insert(rc[root],mid+1,r,x); if(maxx[lc[root]]>=maxx[rc[root]]) maxx[root]=maxx[lc[root]],num[root]=num[lc[root]]; else maxx[root]=maxx[rc[root]],num[root]=num[rc[root]]; } void decrease(int &root,int l,int r,int x) { if(!root) root=++sz; cnt[root]--; if(l==r) { maxx[root]=cnt[root]; num[root]=maxx[root]<=0?0:l; return; } int mid=(l+r)/2; if(x<=mid) decrease(lc[root],l,mid,x); else decrease(rc[root],mid+1,r,x); if(maxx[lc[root]]>=maxx[rc[root]]) maxx[root]=maxx[lc[root]],num[root]=num[lc[root]]; else maxx[root]=maxx[rc[root]],num[root]=num[rc[root]]; } int merge(int x,int y,int l,int r) { if(!x||!y) return x+y; cnt[x]+=cnt[y]; if(l==r) { maxx[x]=cnt[x]; num[x]=maxx[x]<=0?0:l; return x; } int mid=(l+r)/2; lc[x]=merge(lc[x],lc[y],l,mid); rc[x]=merge(rc[x],rc[y],mid+1,r); if(maxx[lc[x]]>=maxx[rc[x]]) maxx[x]=maxx[lc[x]],num[x]=num[lc[x]]; else maxx[x]=maxx[rc[x]],num[x]=num[rc[x]]; return x; } void dfst(int x) { for(int i=head[x];i;i=line[i].next) { int v=line[i].to; if(!mark[v]) { mark[v]=1; dfst(v); root[x]=merge(root[x],root[v],1,len); } } ans[x]=turn[num[root[x]]]; } int main(){ int x,y; scanf("%d%d",&n,&m); while( (1<<(t+1)) <=n) t++; for(int i=1;i<n;i++) { scanf("%d%d",&x,&y); add(x,y); add(y,x); } deep[1]=1; mark[1]=1; dfs(1); for(int i=1;i<=m;i++) { scanf("%d%d%d",&kpx[i],&kpy[i],&kpz[i]); turn[i]=kpz[i]; } sort(turn+1,turn+1+m); len=unique(turn+1,turn+1+m)-(turn+1); for(int i=1;i<=m;i++) { kpz[i]=lower_bound(turn+1,turn+1+len,kpz[i])-turn; } for(int i=1;i<=m;i++) { x=ask(kpx[i],kpy[i]); if(x==kpx[i]) { insert(root[ kpy[i] ],1,len,kpz[i]); decrease(root[ f[x][0] ],1,len,kpz[i]); continue; } if(x==kpy[i]) { insert(root[ kpx[i] ],1,len,kpz[i]); decrease(root[ f[x][0] ],1,len,kpz[i]); continue; } insert(root[ kpx[i] ],1,len,kpz[i]); insert(root[ kpy[i] ],1,len,kpz[i]); decrease(root[x],1,len,kpz[i]); decrease(root[ f[x][0] ],1,len,kpz[i]); } memset(mark,0,sizeof(mark)); mark[1]=1; dfst(1); for(int i=1;i<=n;i++) { printf("%d\n",ans[i]); } } 

Guess you like

Origin www.cnblogs.com/three-D/p/11057979.html