P4556,jzoj3397-[GDOI2014模拟]雨天的尾巴【树链剖分,线段树】
生活随笔
收集整理的這篇文章主要介紹了
P4556,jzoj3397-[GDOI2014模拟]雨天的尾巴【树链剖分,线段树】
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
正題
題目鏈接:https://www.luogu.org/problemnew/show/P4556
題目大意
nnn個點(diǎn)的一棵樹,給出mmm個操作(x,y,z)(x,y,z)(x,y,z)表示將xxx到yyy的路徑上的所有點(diǎn)給與一個zzz類型的食量。
最后對于每個點(diǎn)輸出最多的糧食類型。
解題思路
先對這棵樹進(jìn)行樹剖,然后對于每個x,yx,yx,y我們將其拆成若干條在重鏈上連續(xù)的路徑,然后我們就可以對于每一條重鏈單獨(dú)進(jìn)行操作,這樣就成為了一個序列問題。
將zzz離散化以后再線段樹上進(jìn)行操作,維護(hù)一個(w,loc)(w,loc)(w,loc)表示最多的糧食數(shù),這個糧食的類型。然后每次遇到一個左端點(diǎn)就在zzz處+1+1+1,遇到右端點(diǎn)就在zzz處?1-1?1。
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int N=110000; struct Edge_node{int to,next; }a[N<<1]; struct Path_node{int w,z; }q[N*30]; struct Tree_node{int l,r,w,loc; }; int n,m,cnt,tot,ls[N],fa[N],from[N],ans[N]; int b[N],seg[N],id[N],siz[N],son[N],dep[N],top[N]; struct Seg_Tree{Tree_node t[N<<2]; void Merge(int x,int ls,int rs){t[x].w=max(t[ls].w,t[rs].w);if(t[x].w==t[ls].w) t[x].loc=t[ls].loc;else t[x].loc=t[rs].loc;}void Build(int x,int l,int r){t[x].l=l;t[x].r=r;if(l==r){t[x].w=0;t[x].loc=0;return;}int mid=(l+r)/2;Build(x*2,l,mid);Build(x*2+1,mid+1,r);Merge(x,x*2,x*2+1);}void Change(int x,int pos,int w){if(t[x].l==t[x].r){t[x].w+=w;t[x].loc=pos;if(!t[x].w) t[x].loc=0;return;}if(pos<=t[x*2].r) Change(x*2,pos,w);else Change(x*2+1,pos,w);Merge(x,x*2,x*2+1);}int Query(){return t[1].loc;} }Tree; void addl(int x,int y) {a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot; } void dfs1(int x) {siz[x]=1;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa[x]) continue;dep[y]=dep[x]+1;fa[y]=x;dfs1(y);siz[x]+=siz[y];if(siz[y]>siz[son[x]]) son[x]=y;} } void dfs2(int x) {seg[x]=++cnt;id[cnt]=x;from[cnt]=top[x];if(son[x]){top[son[x]]=top[x];dfs2(son[x]);}for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa[x]||y==son[x]) continue;top[y]=y;dfs2(y);} } void Apart_path(int x,int y,int z) {while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]]) swap(x,y);q[++cnt]=(Path_node){seg[top[x]],z};q[++cnt]=(Path_node){seg[x]+1,-z};x=fa[top[x]];}if(dep[x]>dep[y]) swap(x,y);q[++cnt]=(Path_node){seg[x],z};q[++cnt]=(Path_node){seg[y]+1,-z}; } bool cmp(Path_node x,Path_node y) {return x.w<y.w;} int main() {scanf("%d%d",&n,&m);for(int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);addl(x,y);addl(y,x);}dfs1(1);dfs2(1);cnt=0;for(int i=1;i<=m;i++){int x,y,w;scanf("%d%d%d",&x,&y,&w);Apart_path(x,y,w);b[i]=w;}sort(b+1,b+1+m);m=unique(b+1,b+1+m)-b-1;sort(q+1,q+1+cnt,cmp);int l=1;Tree.Build(1,1,max(m,1));for(int i=1;i<=n;i++){while(q[l].w<=i&&l<=cnt){int w=lower_bound(b+1,b+1+m,abs(q[l].z))-b;Tree.Change(1,w,(q[l].z<0)?-1:1);l++;}ans[id[i]]=b[Tree.Query()];}for(int i=1;i<=n;i++)printf("%d\n",ans[i]); }總結(jié)
以上是生活随笔為你收集整理的P4556,jzoj3397-[GDOI2014模拟]雨天的尾巴【树链剖分,线段树】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 冰冻三尺是什么意思 词语冰冻三尺是什么意
- 下一篇: 特长有哪些 个人特长包括哪些