P8264 [Ynoi Easy Round 2020] TEST_100 题解
前言
来个无脑分块做法,不需要并查集。
正文
首先有一个结论,观察到绝对值函数
现在给定了一个长度为
- 当
s=t 时直接计算。 - 当
a_{s}\in \left[l,r\right] 再进行一个分类讨论- 当
a_s-l\geq r-a_s 时,递归处理x\in\left[0,a_s-l\right] 的f_{s+1,t} ,得到x\in\left[l,a_s\right] 的f_{s,t}\left(x\right)=f_{s+1,t}\left(a_s-\left(x-l\right)\right) ,然后根据对称轴填充另一部分f_{s,t}\left(x\right)=f_{s,t}\left(2a_s-x\right) 。 - 反正同理。
- 当
- 否则,进行一个分类讨论:
- 当
a_s\le l 时,递归处理x\in\left[l-a_s,r-a_s\right] 的f_{s+1,t} ,得到x\in\left[l,a_s\right] 的f_{s,t}\left(x\right)=f_{s+1,t}\left(x-l\right) 。 - 反之同理。
- 当
这样处理每一个块只需要填
代码
代码实现上可以用一个函数 solve(l,r,s,t) 表示需要解决
AC CODE
#include<bits/stdc++.h>
// #define ONLINE_JUDGE
#define INPUT_DATA_TYPE int
#define OUTPUT_DATA_TYPE int
INPUT_DATA_TYPE read(){register INPUT_DATA_TYPE x=0;register char f=0,c=getchar();while(c<'0'||'9'<c)f=(c=='-'),c=getchar();while('0'<=c&&c<='9')x=(x<<3)+(x<<1)+(c&15),c=getchar();return f?-x:x;}void print(OUTPUT_DATA_TYPE x){if(x<0)x=-x,putchar('-');if(x>9)print(x/10);putchar(x%10^48);return;}
const int NNNN=100010;
const int MMMM=1010;
// const int NNNN=110;
// const int MMMM=110;
int V=NNNN-5;
int abss(int x){return x<0?-x:x;}
struct BA{
int len,cnt,id[NNNN],arr[NNNN],F[MMMM][NNNN],L[MMMM],R[MMMM],tag[MMMM];
void build(int n,int *data){
register int i;
len=std::sqrt(n)*3;
cnt=n/len;
if(n%len) ++cnt;
for(i=1;i<=n;++i) arr[i]=data[i],id[i]=(i-1)/len+1;
for(i=1;i<=cnt;++i) L[i]=(i-1)*len+1,R[i]=i*len,buildB(i);
R[cnt]=n;
return;
}
void solve(int l,int r,int s,int t,int id,int now,int end){
register int i;
if(s>t) s=arr[now]-s+arr[now],t=arr[now]-t+arr[now];
if(now==end){
for(i=l;i<=r;++i)
F[id][i]=abss(i-l+s-arr[now]);
return;
}
if(s<arr[now]&&arr[now]<t){
if(arr[now]-s>t-arr[now]){
solve(l,l+arr[now]-s,arr[now]-s,0,id,now+1,end);
for(i=l+arr[now]-s+1;i<=r;++i)
F[id][i]=F[id][(l+arr[now]-s)-(i-(l+arr[now]-s))];
}else{
solve(l+arr[now]-s,r,0,t-arr[now],id,now+1,end);
for(i=l;i<l+arr[now]-s;++i)
F[id][i]=F[id][(l+arr[now]-s)+((l+arr[now]-s)-i)];
}
}else solve(l,r,abss(s-arr[now]),abss(t-arr[now]),id,now+1,end);
return;
}
void buildB(int id){
return solve(0,V,0,V,id,L[id],R[id]);
}
int query(int l,int r,int x){
register int i;
int begin=id[l],end=id[r];
if(begin==end){
for(i=l;i<=r;++i) x=abss(x-arr[i]);
return x;
}
for(i=l;id[i]==begin;++i)
x=abss(x-arr[i]);
for(i=begin+1;i<end;++i)
x=F[i][x];
for(i=L[end];i<=r;++i)
x=abss(x-arr[i]);
return x;
}
}ba;
int arr[100010];
int main(){
#ifndef ONLINE_JUDGE
freopen("name.in", "r", stdin);
freopen("name.out", "w", stdout);
#endif
register int i,latans=0,l,r,x;
int n=read();
int q=read();
for(i=1;i<=n;++i) arr[i]=read();
ba.build(n,arr);
for(i=0;i<q;++i){
l=read()^latans;
r=read()^latans;
x=read()^latans;
print(latans=ba.query(l,r,x)),putchar('\n');
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}