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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

BZOJ2759 一个动态树好题

發布時間:2025/3/15 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ2759 一个动态树好题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目

\(N\)個未知數\(x[1..n]\)\(N\)個等式組成的同余方程組:
\(x[i]=k[i]*x[p[i]]+b[i] mod 10007\)
其中,\(k[i],b[i],x[i]∈[0,10007)∩Z\)
你要應付\(Q\)個事務,每個是兩種情況之一:
一.詢問當前\(x[a]\)的解
\(A\ a\)
無解輸出-1
\(x[a]\)有多解輸出-2
否則輸出\(x[a]\)
二.修改一個等式
\(C\ a\ k[a]\ p[a]\ b[a]\)

思路1

此題一直有點迷,在paulliant大佬的指點下,勉強口胡一份題解。

首先不難發現,這是一個樹形結構,每個點僅有一條有向出邊,知道了每個點的父親就能知道這個點,所以這是一棵基環樹,然后我們用一個結構體表示當前點與它父親的依賴關系\((K,B)\)表示\(x=fa[x]*K+B\)

由于是單向邊的有根樹,所以每條邊都指向它的父親。所以對于LCT中的一條路徑\((u,v)\)來說,\(sum[rt]=(node){K,B}\)表示\(u=Kv+B\),合并什么的還是很好推的。

還有一題小R與手機和此題有幾分相像。

struct node{int k,b;node operator + (const node& res)const{return (node){k*res.k%P,(res.k*b%P+res.b)%P};} }

然后如果存在了環的話,可以先把它存下來,等之后有點被刪掉了之后在加上去。之后詢問的時候由于形成了環,所以就可以得到解的情況了。

代碼

#include<bits/stdc++.h> #define M 100005 using namespace std; const int P=1e4+7; int inv[M],Ifa[M]; int n; struct node{int k,b;node operator + (const node& res)const{return (node){k*res.k%P,(res.k*b%P+res.b)%P};} }val[M],sum[M]; struct LCT{int ch[M][2],fa[M];void up(int p){sum[p]=sum[ch[p][0]]+val[p]+sum[ch[p][1]];}void create(int x,node d){ch[x][0]=ch[x][1]=fa[x]=0;val[x]=sum[x]=d;}bool isrt(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}void rotate(int x){int y=fa[x],z=fa[y],k=ch[y][1]==x;if(!isrt(y))ch[z][ch[z][1]==y]=x;fa[x]=z;ch[y][k]=ch[x][!k];fa[ch[x][!k]]=y;ch[x][!k]=y;fa[y]=x;up(y);up(x);}void splay(int x){while(!isrt(x)){int y=fa[x],z=fa[y];if(!isrt(y))(ch[y][1]==x^ch[z][1]==y)?rotate(x):rotate(y);rotate(x);}}void access(int x){for(int y=0;x;y=x,x=fa[x])splay(x),ch[x][1]=y,up(x);}int findrt(int x){access(x);splay(x);while(ch[x][0])x=ch[x][0];splay(x);return x;}bool link(int x,int y){splay(x);if(findrt(y)==x)return 0;fa[x]=y;return 1;}bool cut(int x){access(x),splay(x);if(!ch[x][0])return 0;fa[ch[x][0]]=0;ch[x][0]=0;up(x);return 1;}void update(int x,node d){val[x]=sum[x]=d;up(x);splay(x);}node query(int x){access(x),splay(x);return sum[x];}void Link(int x,int y){if(!link(x,y))Ifa[x]=y;}void Cut(int x){int y=findrt(x);if(!cut(x)){Ifa[x]=0;return;}if(link(y,Ifa[y]))Ifa[y]=0;}int solve(int x){int y=findrt(x),z=Ifa[y];node f=query(z);if(f.k==1)return f.b==0?-2:-1;int vl=f.b*inv[(P+1-f.k)%P]%P;f=query(x);return (f.k*vl+f.b)%P;} }Tr; int main(){inv[0]=inv[1]=1;for(int i=2;i<=P-1;i++)inv[i]=(P-P/i)*inv[P%i]%P;scanf("%d",&n);for(int i=0;i<=n;i++)Tr.create(i,(node){1,0});for(int i=1;i<=n;i++){int k,p,b;scanf("%d%d%d",&k,&p,&b);Tr.update(i,(node){k,b});Tr.Link(i,p);}int q;scanf("%d",&q);while(q--){char op[5];int a,k,p,b;scanf("%s",op);if(op[0]=='A'){scanf("%d",&a);printf("%d\n",Tr.solve(a));}else {scanf("%d%d%d%d",&a,&k,&p,&b);Tr.update(a,(node){k,b});Tr.Cut(a);Tr.Link(a,p);}}return 0; }
  • [BZOJ 2759 一個動態樹好題(動態樹)]?

  • 轉載于:https://www.cnblogs.com/zryabc/p/10701390.html

    總結

    以上是生活随笔為你收集整理的BZOJ2759 一个动态树好题的全部內容,希望文章能夠幫你解決所遇到的問題。

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