标签:xid add \n bzoj ble namespace 合并 fine int
树上差分+线段树合并+离散化
对于修改的路径,树上差分就好了
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<tr1/unordered_map>
#include<algorithm>
using namespace std;
void read(int &x) {
char ch; bool ok;
for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
}
#define rg register
const int maxn=1e5+10;
int dep[maxn],n,m,id,tot,pre[maxn*2],rt[maxn],ls[maxn*50],f[maxn][20],x[maxn],y[maxn],z[maxn],nid[maxn];
int rs[maxn*50],mx[maxn*50],mxid[maxn*50],nxt[maxn*2],h[maxn],cnt,ans[maxn],w[maxn];tr1::unordered_map<int,int>mp;
bool vis[maxn];
void add(int x,int y)
{
pre[++cnt]=y,nxt[cnt]=h[x],h[x]=cnt;
pre[++cnt]=x,nxt[cnt]=h[y],h[y]=cnt;
}
void dfs(int x,int fa)
{
for(rg int i=1;i<20;i++)
{
if((1<<i)>dep[x])break;
f[x][i]=f[f[x][i-1]][i-1];
}
for(rg int i=h[x];i;i=nxt[i])
if(pre[i]!=fa)f[pre[i]][0]=x,dep[pre[i]]=dep[x]+1,dfs(pre[i],x);
}
int lca(int x,int y)
{
if(dep[x]>dep[y])swap(x,y);
int poor=dep[y]-dep[x];
for(rg int i=19;i>=0;i--)if(poor&(1<<i))y=f[y][i];
if(x==y)return x;
for(rg int i=19;i>=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
return x==y?x:f[x][0];
}
void update(int x)
{
if(mx[ls[x]]>mx[rs[x]]||(mx[ls[x]]==mx[rs[x]]&&mxid[ls[x]]<mxid[rs[x]]))mx[x]=mx[ls[x]],mxid[x]=mxid[ls[x]];
else if(mx[ls[x]]<mx[rs[x]]||(mx[ls[x]]==mx[rs[x]]&&mxid[ls[x]]>mxid[rs[x]]))mx[x]=mx[rs[x]],mxid[x]=mxid[rs[x]];
}
void change(int &k,int l,int r,int a,int b)
{
if(!k)k=++id;int mid=(l+r)>>1;
if(l==r){mx[k]+=b,mxid[k]=l;return ;}
if(a<=mid)change(ls[k],l,mid,a,b);
else change(rs[k],mid+1,r,a,b);
update(k);
}
int merge(int x,int y,int l,int r)
{
if(!x||!y)return x+y;
int mid=(l+r)>>1;
ls[x]=merge(ls[x],ls[y],l,mid);
rs[x]=merge(rs[x],rs[y],mid+1,r);
if(l==r)mx[x]+=mx[y];else update(x);
return x;
}
void solve(int x,int fa)
{
for(rg int i=h[x];i;i=nxt[i])
if(pre[i]!=fa)
{
solve(pre[i],x);
rt[x]=merge(rt[x],rt[pre[i]],1,tot);
}
ans[x]=nid[mxid[rt[x]]];
}
int main()
{
read(n),read(m);
for(rg int i=1,x,y;i<n;i++)read(x),read(y),add(x,y);
dfs(1,0);
for(rg int i=1;i<=m;i++)read(x[i]),read(y[i]),read(z[i]),w[i]=z[i];
sort(w+1,w+m+1);tot=0;
for(rg int i=1;i<=m;i++)if(w[i]!=w[i-1])mp[w[i]]=++tot,nid[tot]=w[i];
for(rg int i=1;i<=m;i++)
{
int fa=lca(x[i],y[i]);
change(rt[x[i]],1,tot,mp[z[i]],1),change(rt[y[i]],1,tot,mp[z[i]],1),
change(rt[fa],1,tot,mp[z[i]],-1),change(rt[f[fa][0]],1,tot,mp[z[i]],-1);
}
solve(1,0);
for(rg int i=1;i<=n;i++)printf("%d\n",ans[i]);
}
标签:xid add \n bzoj ble namespace 合并 fine int
原文地址:https://www.cnblogs.com/lcxer/p/10604150.html