日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

P4556,jzoj3397-[GDOI2014模拟]雨天的尾巴【树链剖分,线段树】

發布時間:2023/12/3 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P4556,jzoj3397-[GDOI2014模拟]雨天的尾巴【树链剖分,线段树】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.org/problemnew/show/P4556


題目大意

nnn個點的一棵樹,給出mmm個操作(x,y,z)(x,y,z)(x,y,z)表示將xxxyyy的路徑上的所有點給與一個zzz類型的食量。

最后對于每個點輸出最多的糧食類型。


解題思路

先對這棵樹進行樹剖,然后對于每個x,yx,yx,y我們將其拆成若干條在重鏈上連續的路徑,然后我們就可以對于每一條重鏈單獨進行操作,這樣就成為了一個序列問題。

zzz離散化以后再線段樹上進行操作,維護一個(w,loc)(w,loc)(w,loc)表示最多的糧食數,這個糧食的類型。然后每次遇到一個左端點就在zzz+1+1+1,遇到右端點就在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]); }

總結

以上是生活随笔為你收集整理的P4556,jzoj3397-[GDOI2014模拟]雨天的尾巴【树链剖分,线段树】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。