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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ2759 一个动态树好题

發(fā)布時(shí)間:2025/3/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ2759 一个动态树好题 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目

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

思路1

此題一直有點(diǎn)迷,在paulliant大佬的指點(diǎn)下,勉強(qiáng)口胡一份題解。

首先不難發(fā)現(xiàn),這是一個(gè)樹形結(jié)構(gòu),每個(gè)點(diǎn)僅有一條有向出邊,知道了每個(gè)點(diǎn)的父親就能知道這個(gè)點(diǎn),所以這是一棵基環(huán)樹,然后我們用一個(gè)結(jié)構(gòu)體表示當(dāng)前點(diǎn)與它父親的依賴關(guān)系\((K,B)\)表示\(x=fa[x]*K+B\)

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

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

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

然后如果存在了環(huán)的話,可以先把它存下來(lái),等之后有點(diǎn)被刪掉了之后在加上去。之后詢問(wèn)的時(shí)候由于形成了環(huán),所以就可以得到解的情況了。

代碼

#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 一個(gè)動(dòng)態(tài)樹好題(動(dòng)態(tài)樹)]?

  • 轉(zhuǎn)載于:https://www.cnblogs.com/zryabc/p/10701390.html

    總結(jié)

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

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。