洛谷 P3203 [HNOI2010]彈飛綿羊 解題報告
阿新 • • 發佈:2018-08-11
然而 整數 n) mon 輸入格式 roo data 直接 query
一下然後直接斷虛邊
P3203 [HNOI2010]彈飛綿羊
題目描述
某天,Lostmonkey發明了一種超級彈力裝置,為了在他的綿羊朋友面前顯擺,他邀請小綿羊一起玩個遊戲。遊戲一開始,Lostmonkey在地上沿著一條直線擺上n個裝置,每個裝置設定初始彈力系數ki,當綿羊達到第i個裝置時,它會往後彈ki步,達到第i+ki個裝置,若不存在第i+ki個裝置,則綿羊被彈飛。綿羊想知道當它從第i個裝置起步時,被彈幾次後會被彈飛。為了使得遊戲更有趣,Lostmonkey可以修改某個彈力裝置的彈力系數,任何時候彈力系數均為正整數。
輸入輸出格式
輸入格式:
第一行包含一個整數n,表示地上有n個裝置,裝置的編號從0到n-1。
接下來一行有n個正整數,依次為那n個裝置的初始彈力系數。
第三行有一個正整數m,
接下來m行每行至少有兩個數i、j,若i=1,你要輸出從j出發被彈幾次後被彈飛,若i=2則還會再輸入一個正整數k,表示第j個彈力裝置的系數被修改成k。
輸出格式:
對於每個i=1的情況,你都要輸出一個需要的步數,占一行。
說明
對於20%的數據n,m<=10000,對於100%的數據n<=200000,m<=100000
抽象一下問題,將彈飛的連到虛點\(n+1\)上,則圖是一顆樹,我們需要一個能修改邊的,查詢深度的連喵樹。
我們發現其實不需要換根操作(然而本菜雞最開始還打了)
\(link\)時提一個連一個虛邊就行了
\(cat\)的時候把淺的\(access\)上去以後把深的\(splay\)
\(query\)時\(access\)一下,\(splay\)一下,就是左兒子大小。
事實上可以更簡單
Code:
#include <cstdio> #define ls ch[now][0] #define rs ch[now][1] #define fa par[now] int min(int x,int y){return x<y?x:y;} const int N=2e5+10; int ch[N][2],siz[N],par[N],n,m,tmp,to[N]; bool isroot(int now) { return ch[fa][0]==now||ch[fa][1]==now; } int identity(int now) { return ch[fa][1]==now; } void updata(int now) { siz[now]=siz[ls]+siz[rs]+1; } void connect(int f,int now,int typ) { fa=f;ch[f][typ]=now; } void Rotote(int now) { int p=fa,typ=identity(now); connect(p,ch[now][typ^1],typ); if(isroot(p)) connect(par[p],now,identity(p)); else fa=par[p]; connect(now,p,typ^1); updata(p),updata(now); } void splay(int now) { for(;isroot(now);Rotote(now)) if(isroot(fa)) Rotote(identity(now)^identity(fa)?now:fa); } void access(int now) { for(int las=0;now;las=now,now=fa) splay(now),rs=las,updata(now); } void link(int u,int v) { access(v); splay(u); par[u]=v; } void cat(int u,int v) { access(v); splay(u); par[u]=0; } int query(int now) { access(now); splay(now); return siz[ls]; } int main() { scanf("%d",&n); for(int k,i=1;i<=n;i++) { scanf("%d",&k); par[i]=min(i+k,n+1); to[i]=par[i]; } scanf("%d",&m); for(int op,u,k,i=1;i<=m;i++) { scanf("%d%d",&op,&u);++u; if(op==1) printf("%d\n",query(u)); else { scanf("%d",&k); cat(u,to[u]); to[u]=min(u+k,n+1); link(u,to[u]); } } return 0; }
2018.8.11
洛谷 P3203 [HNOI2010]彈飛綿羊 解題報告