Bzoj-2002&&Luogu-3203&CodeVS-2333
阿新 • • 發佈:2018-01-15
當前 esp 以及 能夠 img line min while 維護 怎麽做呢qwq,思考√n修改+√n查詢,那麽就把整段序列劃分為√n段,對於每一個點預處理出它被彈出當前這個塊需要幾次,以及跳到這個塊之外的什麽地方,修改時需要成塊修改,這樣的話在同一個塊中以當前點為跳板的點“被彈出當前這個塊需要幾次,以及跳到這個塊之外的什麽地方”才能夠正確維護qwq,之前沒註意到這個w了好多次啊T T,當然我語文菜啊T T,表述不清的請評論告訴我QWQ
對比一下zz的分塊QwQ
貌似因為加了快讀所以比zz快了不少,當然還有一個原因是pascal大法qwq,一年前就聽說這道題了,一直鴿了
眾所周知(藍鵝好像並不),分塊是一種騙分的大法qwq。一直聽說這是一道分塊題,就來寫寫T T,卡了一晚上差點就看題解了QwQ
首先這道題貌似是有log級別的算法的(lct貌似就是),但是不會啊T T。數據範圍資瓷$logn$和$√n$算法的,不過貌似lct的常數比較大,跑一波下來比分塊還慢T T。
怎麽做呢qwq,思考√n修改+√n查詢,那麽就把整段序列劃分為√n段,對於每一個點預處理出它被彈出當前這個塊需要幾次,以及跳到這個塊之外的什麽地方,修改時需要成塊修改,這樣的話在同一個塊中以當前點為跳板的點“被彈出當前這個塊需要幾次,以及跳到這個塊之外的什麽地方”才能夠正確維護qwq,之前沒註意到這個w了好多次啊T T,當然我語文菜啊T T,表述不清的請評論告訴我QWQ
#include<cstdio> #include<cmath> #include<algorithm> #include<iostream> using namespace std; #define ll long long #define inf 0x7fffffff inline int read() { int x=0,f=1;char c=getchar(); while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} return x*f; } int n,siz,m; int x[200005],nxt[200005],bl[200005],num[200005]; int main() { n=read();siz=sqrt(n-1)+1; for(int i=1;i<=n;i++)x[i]=read(),nxt[i]=i,bl[i]=(i-1)/siz+1; for(int i=1;i<=n;i++)while(nxt[i]<=min(bl[i]*siz,n)){num[i]++;nxt[i]=nxt[i]+x[nxt[i]];} m=read(); while(m--) { int st=read(); if(st==1) { int now=read()+1,ans=0; while(now<=n) ans+=num[now],now=nxt[now]; printf("%d\n",ans); } else if(st==2) { int id=read()+1,r=min(bl[id]*siz,n),l=max((bl[id]-1)*siz+1,1);x[id]=read(); for(int i=r;i>=l;i--) if(i+x[i]>min(bl[id]*siz,n)){nxt[i]=i+x[i];num[i]=1;} else{nxt[i]=nxt[i+x[i]];num[i]=num[i+x[i]]+1;} //while(nxt[id]<=min(bl[id]*siz,n)){num[id]++;nxt[id]=nxt[id]+x[nxt[id]];} } } return 0; }
Bzoj-2002&&Luogu-3203&CodeVS-2333