P4855 MloVtry的idea 题解
P4855题解
思路
这道题乍一看非常不可做,要实现区间加一个数,区间加等差数列和区间第
不过手玩样例后可以发现每次查询中对
而且因为
因此,不难想到分两部分处理。
再思考
做法
由于要区间第
用两棵主席树分别维护
对于每次查询,由于不便于(或者我太蒟)直接查询第
二分一个最小在当前的
小于等于
AC代码
#include<bits/stdc++.h>
#define R(x) x=read()
using namespace std;
char pbuf[1<<20], *pp=pbuf;
void swap(int &a,int &b){a^=b^=a^=b;}
inline void push(const char &c){if(pp - pbuf == 1<<20)fwrite(pbuf, 1, 1<<20, stdout),pp = pbuf;*pp++ = c;}
class io{public:~io(){fwrite(pbuf, 1, pp - pbuf, stdout);}}_;
inline void write(int x) {
if (x<0)x=-x,push('-');
int sta[35],top=0;
do{sta[top++]=x%10,x/=10;}while (x);
while(top)push(sta[--top]^'0');
}
#ifndef LOCAL
char buf[1<<23],*p1=buf,*p2=buf,obuf[1<<23],*O=obuf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
inline int read() {
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
return x*f;
}
int n,q,zz;
#define N 60010
int a[N];
struct node{
int ls,rs,s;
}t[N<<6];
int siz;
int rt[N],r2[N];
void update(int u,int v,int l,int r,int pos){
t[v].s=t[u].s+1;
if(l==r)return;
int mid=(l+r)>>1;
if(!t[u].ls)t[u].ls=++siz;
if(!t[u].ls)t[u].rs=++siz;
t[v].ls=t[u].ls;
t[v].rs=t[u].rs;
if(pos<=mid){
t[v].ls=++siz;
update(t[u].ls,t[v].ls,l,mid,pos);
}
else{
t[v].rs=++siz;
update(t[u].rs,t[v].rs,mid+1,r,pos);
}
}
int query(int u,int v,int l,int r,int x){
if(l==r)return t[v].s-t[u].s;
int mid=(l+r)>>1;
if(x<=mid)return query(t[u].ls,t[v].ls,l,mid,x);
else return t[t[v].ls].s-t[t[u].ls].s+query(t[u].rs,t[v].rs,mid+1,r,x);
}
int ls;
signed main(){
R(n);R(q);R(zz);
for(int i=1;i<=n;i++)R(a[i]);
rt[0]=++siz;
r2[0]=++siz;
for(int i=1;i<=n;i++){
rt[i]=++siz;
r2[i]=++siz;
update(rt[i-1],rt[i],-1e9,1e9,a[i]-zz);
update(r2[i-1],r2[i],-1e9,1e9,a[i]+i);
}
while(q--){
int R(j),R(k);
j=(j^ls)%n+1;
k=(k^ls)%n+1;
int l=-1e9,r=1e9;
while(l<r){
int mid=(l+r)>>1;
if(query(rt[0],rt[j],-1e9,1e9,mid)+query(r2[j],r2[n],-1e9,1e9,mid+j)>=k)r=mid;
else l=mid+1;
}
// for(int i=1;i<=n;i++){
// if(i<=j)write(a[i]-zz);
// else write(a[i]-j+i);
// push(' ');
// }
// push('\n');
// int x=11932;
// write(query(rt[0],rt[j],-1e9,1e9,x));write(query(r2[j],r2[n],-1e9,1e9,x+j));push('\n');
// write(j);push(' ');
// write(k);push('|');
write(l);
// push(' ');
// write(query(rt[0],rt[j],-1e9,1e9,l));write(query(r2[j],r2[n],-1e9,1e9,l+j));
push('\n');
ls=l>0?l:-l;
}
return 0;
}