bzoj3307: 雨天的尾巴
作者:互联网
Star_Feel大爷是最强的
这道题我的想法是把每种数字分开做,然后再合并
现在不知道为什么就写了这种树上差分+下标是数字的线段树合并(其实都一样)
那就这样吧
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #define mid (ql+qr)/2 using namespace std; const int _=1e2; const int maxn=1e5+_; const int bit=30; //---------------------------------------def----------------------------------------------------- struct node { int x,y,next; }a[2*maxn];int len,last[maxn]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } int Bin[bit],f[bit][maxn],dep[maxn]; void dfs(int x) { for(int i=1;dep[x]>=Bin[i];i++)f[i][x]=f[i-1][f[i-1][x]]; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(y!=f[0][x]) { f[0][y]=x; dep[y]=dep[x]+1; dfs(y); } } } int LCA(int x,int y) { if(dep[x]<dep[y])swap(x,y); for(int i=25;i>=0;i--) if(dep[x]-dep[y]>=Bin[i])x=f[i][x]; if(x==y)return x; for(int i=25;i>=0;i--) if(dep[x]>=Bin[i]&&f[i][x]!=f[i][y])x=f[i][x],y=f[i][y]; return f[0][x]; } //---------------------------------------prepare----------------------------------------------------- struct trnode { int lc,rc,mx,id; }tr[maxn*60];int trlen,rt[maxn]; void update(int now) { int lc=tr[now].lc,rc=tr[now].rc; if(tr[lc].mx>=tr[rc].mx||rc==0) tr[now].mx=tr[lc].mx,tr[now].id=tr[lc].id; else tr[now].mx=tr[rc].mx,tr[now].id=tr[rc].id; } //~~~~~~~~~~~~~~~~~in~~~~~~~~~~~~~~~~~~~~ int change(int now,int ql,int qr,int p,int d) { if(now==0)now=++trlen,tr[now].mx=ql==qr?0:-(1<<30); if(ql==qr){tr[now].mx+=d;tr[now].id=p;return now;} if(p<=mid)tr[now].lc=change(tr[now].lc,ql,mid,p,d); else tr[now].rc=change(tr[now].rc,mid+1,qr,p,d); update(now);return now; } int merge(int x,int y,int ql,int qr) { if(x==0||y==0)return x+y; if(ql==qr){tr[x].mx+=tr[y].mx;return x;} tr[x].lc=merge(tr[x].lc,tr[y].lc,ql,mid); tr[x].rc=merge(tr[x].rc,tr[y].rc,mid+1,qr); update(x);return x; } //~~~~~~~~~~~~~~~~~out~~~~~~~~~~~~~~~~~~~~ //---------------------------------------segtree----------------------------------------------------- struct query{int x,y,p;}q[maxn]; int lslen,ls[maxn]; int as[maxn]; void solve(int x) { for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(y!=f[0][x]) { solve(y); rt[x]=merge(rt[x],rt[y],1,lslen); } } as[x]=ls[tr[rt[x]].id]; } int main() { int n,m,x,y,p; scanf("%d%d",&n,&m); len=1; for(int i=1;i<n;i++) { scanf("%d%d",&x,&y); ins(x,y),ins(y,x); } Bin[0]=1;for(int i=1;i<=25;i++)Bin[i]=Bin[i-1]*2; dfs(1); for(int i=1;i<=m;i++) scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].p),ls[++lslen]=q[i].p; sort(ls+1,ls+lslen+1); lslen=unique(ls+1,ls+lslen+1)-ls-1; for(int i=1;i<=m;i++) q[i].p=lower_bound(ls+1,ls+lslen+1,q[i].p)-ls; trlen=0; for(int i=1;i<=m;i++) { x=q[i].x,y=q[i].y,p=q[i].p; int lca=LCA(x,y); rt[x]=change(rt[x],1,lslen,p,1); rt[y]=change(rt[y],1,lslen,p,1); rt[lca]=change(rt[lca],1,lslen,p,-1); if(lca!=1)rt[f[0][lca]]=change(rt[f[0][lca]],1,lslen,p,-1); } solve(1); for(int i=1;i<=n;i++)printf("%d\n",as[i]); return 0; }
标签:int,尾巴,tr,dep,bzoj3307,雨天,maxn,now,mx 来源: https://www.cnblogs.com/AKCqhzdy/p/10345251.html