日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【LCT】遥远的国度(P3979)

發布時間:2023/12/3 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【LCT】遥远的国度(P3979) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

P3979


題目大意

給你一棵樹,讓你進行一下操作:

  • 把根節點修改為x
  • 把x到y路徑上的點權值修改為v
  • 查詢x子樹中的最小權值

  • 解題思路

    可以用LCT維護該樹

    查詢時先make_root(rt)make\_root(rt)make_root(rt),然后把x旋轉到rt的兒子,再計算虛子樹部分即可


    code

    #include<set> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define N 100010 using namespace std; int n,m,x,y,z,rt,top,tot,ans,h[N],D[N]; struct Tree {#define ls son[x][0]#define rs son[x][1]int v[N],w[N],p[N],wl[N],wv[N],pc[N],fa[N],son[N][2];multiset<int>d[N];bool NR(int x){return fa[x]&&(son[fa[x]][0]==x||son[fa[x]][1]==x);}bool IRS(int x){return son[fa[x]][1]==x;}void pushr(int x){if(!x)return;swap(ls,rs);p[x]^=1;return;}void pushc(int x,int y){if(!x)return;wv[x]=v[x]=w[x]=y;w[x]=min(wl[x],wv[x]);pc[x]=1; return;}void push_down(int x){if(!x)return;if(pc[x]){if(ls)pushc(ls,v[x]);if(rs)pushc(rs,v[x]);pc[x]=0;}if(p[x]){if(ls)pushr(ls);if(rs)pushr(rs);p[x]=0; }return;}void push_up(int x){if(!x)return;wl[x]=min(wl[ls],wl[rs]);if(d[x].size())wl[x]=min(wl[x],*d[x].begin());wv[x]=min(v[x],min(wv[ls],wv[rs]));w[x]=min(wl[x],wv[x]);return;}void rotate(int x){int y=fa[x],z=fa[y],k=IRS(x),g=son[x][!k];if(NR(y))son[z][IRS(y)]=x;if(g)fa[g]=y;fa[y]=x;fa[x]=z;son[x][!k]=y;son[y][k]=g;push_up(y);return;}void Splay(int x){int y=x;D[++top]=y;while(NR(y))y=fa[y],D[++top]=y;while(top)push_down(D[top]),top--;while(NR(x)){if(NR(fa[x])){if(IRS(x)==IRS(fa[x]))rotate(fa[x]);else rotate(x);}rotate(x);}push_up(x);return;}void access(int x){for(int y=0;x;x=fa[y=x]){Splay(x);if(rs)d[x].insert(w[rs]);rs=y;if(rs)d[x].erase(d[x].find(w[rs]));push_up(x);}return;}void make_root(int x){access(x);Splay(x);pushr(x);return;}void link(int x,int y){fa[y]=x;d[x].insert(w[y]);return;}void Split(int x,int y){make_root(x);access(y);Splay(y);return;} }T; struct rec {int to,nx; }e[N<<1]; void add(int x,int y) {e[++tot].to=y;e[tot].nx=h[x];h[x]=tot;return; } int read() {char c=getchar();int ds=0,fs=1;while (c<'0'||'9'<c) {if (c=='-') fs=-1;c=getchar();}while (c>='0'&&c<='9') ds=(ds<<3)+(ds<<1)+c-48,c=getchar();return ds*fs; } void dfs(int x,int fa) {for(int i=h[x];i;i=e[i].nx){int y=e[i].to;if(y!=fa){dfs(y,x);T.link(x,y);}}T.push_up(x);return; } int main() {scanf("%d%d",&n,&m);T.v[0]=T.wl[0]=T.wv[0]=T.w[0]=2147483647;for(int i=1;i<n;++i){scanf("%d%d",&x,&y);add(x,y);add(y,x);}for(int i=1;i<=n;++i)T.v[i]=read();scanf("%d",&rt);dfs(rt,0);while(m--){x=read();if(x==1)scanf("%d",&rt);else if(x==2){scanf("%d%d%d",&x,&y,&z);T.Split(x,y);T.pushc(y,z);}else{scanf("%d",&x);T.make_root(rt);T.Split(rt,x);ans=T.v[x];if(T.d[x].size())ans=min(ans,*T.d[x].begin()); //Split中xaccess了,所以沒有右子樹printf("%d\n",ans);}}return 0; }

    總結

    以上是生活随笔為你收集整理的【LCT】遥远的国度(P3979)的全部內容,希望文章能夠幫你解決所遇到的問題。

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