题解:P10680 [COTS/CETS 2024] 双双决斗 Dvoboj

· · 题解

前言

题目描述

upd 复杂度若有误请与我联系。

代码

#include<bits/stdc++.h>
using namespace std;
int n,q;
int st[200010][25];
int p[200010];
int s,t;
void Init(){
    for(int i=1;i<=n;i++){
        st[i][0]=p[i];
    }
    for(int j=1;j<=t;j++){
        for(int i=1;i<=n;i++)if(i+(1<<j)-1<=n){
            st[i][j]=abs(st[i][j-1]-st[i+(1<<(j-1))][j-1]);
        }
    }
    return;
}
int check(int l,int k){
    if(k<=t){
        return st[l][k];
    }
    int ans=abs(check(l,k-1)-check(l+(1<<(k-1)),k-1));
    return ans;
}
int Find(int l,int k){
    if(k<=t){
        int ans=st[l][k];
        return ans;
    }
    int ans=check(l,k);
    return ans;
}
void Work(int id,int r){
    st[id][0]=r;
    for(int j=1;j<=t;j++){
        int w=max(id-(1<<j)+1,1);
        for(int i=w;i<=id;i++)if(i+(1<<j)-1<=n){
            st[i][j]=abs(st[i][j-1]-st[i+(1<<(j-1))][j-1]);
        }
    }
}
int main(){
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++){
        scanf("%d",&p[i]);
    }
    s=sqrt(n);
    t=log2(s);
    Init();
    while(q--){
        int op;
        scanf("%d",&op);
        if(op==1){
            int i,r;
            scanf("%d%d",&i,&r);
            Work(i,r);
        }
        else{
            int l,k;
            scanf("%d%d",&l,&k);
            int ans=Find(l,k);
            printf("%d\n",ans);
        }
    }
    return 0;
}