运交分块欲何求,过完样例全部G(求调)
查看原帖
运交分块欲何求,过完样例全部G(求调)
275989
LingHusama楼主2023/9/4 14:32
#include<bits/stdc++.h>
using namespace std;
#define int long long
int k[200005];
int to[200005];//跳出自己块后将会到达的地点
int cnt[200005];//跳出属于自己块的次数
int sq;
int ingrp(int x){//寻找在哪一个分块中 
	return ceil(1.0*x/sq);
	
} 
int findid(int x){//寻找在分块中的排位 
	if(x%sq!=0)
		return x%sq;
	else
		return sq;
}

signed main(){
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    sq=floor(1.0*sqrt(n));
    for(int i=1;i<=n;i++){
        cin >> k[i];
    }
    for(int i=n;i>=1;i--){
        if(i+k[i]>n){
            to[i]=n+1;
            cnt[i]=1;
            continue;
        }
        int nxt=i+k[i];
        if(ingrp(i)==ingrp(nxt)){//两者在同一块
            to[i]=to[nxt];
            cnt[i]=cnt[nxt]+1;
        }
        else{//两者不在同一块
            to[i]=nxt;
            cnt[i]=1;
        }
    }
    int q;
    cin >> q;
    while(q--){
        int opt;
        cin >> opt;
        if(opt==1){
            int pos;
            cin >> pos;
            pos++;
            int ans=0;
            while(pos!=n+1){
                ans+=cnt[pos];
                pos=to[pos];
            }
            cout<<ans<<endl;
            
        }
        else{
            int x,y;
            cin >> x >> y;//修改x为y。
            x++;
            k[x]=y;
            int gp=ingrp(x);
            int nxt=x+k[x];
            if(nxt>n){
                to[x]=n+1;
                cnt[x]=1;
            }
            else{
                if(gp==ingrp(nxt)){
                    to[x]=nxt;
                    cnt[x]=cnt[nxt]+1;   
                }
                else{
                    to[x]=nxt;
                    cnt[x]=1;
                }
            }//先把这个位置上的修改了;
            for(int i=x-1;i>=1&&ingrp(i)==gp;i--){
                if(i+k[i]>n){
                    to[i]=n+1;
                    cnt[i]=1;
                    continue;
                }
                int nt=i+k[i];
                if(ingrp(i)==ingrp(nt)){//两者在同一块
                    to[i]=to[nt];
                    cnt[i]=cnt[nt]+1;
                }
                else{//两者不在同一块
                    to[i]=nt;
                    cnt[i]=1;
                }
            }
            
        }
    }
}
2023/9/4 14:32
加载中...