题目:点这
跟这题BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 一模一样
分析:
分块数组入门题。
具体的可以学习这篇博文以及做国家集训队2008 - 苏煜《对块状链表的一点研究》这篇论文上面的几道题目。
#include <set> #include <map> #include <cmath> #include <queue> #include <stack> #include <string> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; #define debug puts("here") #define rep(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) #define REP(i,a,b) for(int i=a;i<=b;i++) #define foreach(i,vec) for(unsigned i=0;i<vec.size();i++) #define pb push_back #define RD(n) scanf("%d",&n) #define RD2(x,y) scanf("%d%d",&x,&y) #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w) #define All(vec) vec.begin(),vec.end() #define MP make_pair #define PII pair<int,int> #define PQ priority_queue /******** program ********************/ const int MAXN = 1e5+5; int fa[MAXN],po[MAXN],sz[MAXN],a[MAXN],n,m; int end[MAXN]; void make(int x){ int y = x+a[x]; if(y>n){ end[x] = x; po[x] = n+1; sz[x] = 1; }else{ if(fa[x]==fa[y]){ end[x] = end[y]; po[x] = po[y]; sz[x] = sz[y]+1; }else{ end[x] = x; po[x] = y; sz[x] = 1; } } } void change(int x,int y){ a[x] = y; for(int i=x;i;i--) if(fa[i]==fa[x]) make(i); else break; } void ask(int x){ int s = end[x]; int ans = 0; for(int i=x;i<=n;i=po[i]){ ans += sz[i]; s = end[i]; } printf("%d %d ",s,ans); } int main(){ #ifndef ONLINE_JUDGE freopen("sum.in","r",stdin); //freopen("sum.out","w",stdout); #endif RD2(n,m); int block_size = sqrt(n*1.0); rep1(i,n){ RD(a[i]); fa[i] = i / block_size; } for(int i=n;i;i--) make(i); int x,y,op; while(m--){ RD2(op,x); if(op==0){ RD(y); change(x,y); }else ask(x); } return 0; }