题解 【WR2-2C】【来自地上的支援】
题解
注意到这样一个性质:每次操作选择的值(假设为
这个性质可以这样理解:在第
而选择第
若第
由这个性质,可以发现选择第
\mathcal O(n\log n) 做法
现在把一段等差数列压成一段一起维护,记录每一段的首项位置。
然后用一个指针
先讲一下这个东西怎么维护:每次从
- 如果一个等差数列的首项选择了
i ,那么这个等差数列会全部选择i ; - 一定是一些连续的等差数列选择
i 。
每次我们可以暴力去删除选择
然后在这些等差数列段上面二分,找到最少选择几个段才能使有
不过这样我们没有考虑
\mathcal O(n) 做法
考虑第
根据刚刚的结论,选择位置
- 第
x 次操作选择了x 位置。 - 第
y 次操作选择了x 位置,其中y=x,x+1,\cdots,x+k-1 。
记
记
为什么呢?此时
现在处理
参考代码
#include<bits/stdc++.h>
#define up(l,r,i) for(int i=l;i<=r;i++)
#define dn(l,r,i) for(int i=l;i>=r;i--)
using namespace std;
typedef long long i64;
const int INF =2147483647;
const int MAXN =1e7+3;
int n,m,v,w,l,F[MAXN],G[MAXN],A[MAXN],X[MAXN],K[MAXN];
i64 ans1,ans2; char _file[256];
int qread(){
int w=1,c,ret;
while((c=getchar())> '9'||c< '0') w=(c=='-'?-1:1); ret=c-'0';
while((c=getchar())>='0'&&c<='9') ret=ret*10+c-'0';
return ret*w;
}
int main(int argc,char **argv){
n=qread(),m=qread(),v=qread();
up(1,n,i) A[i]=qread();
up(1,m,i) X[i]=qread(),K[i]=qread();
A[0]=-INF;
up(1,n,i){
A[i]=w=A[i]-i*v;
if(w>=A[F[i-1]]) G[i]=F[i-1],F[i]=i; else
if(w>=A[G[i-1]]) G[i]=i,F[i]=F[i-1]; else
G[i]=G[i-1],F[i]=F[i-1];
}
up(1,m,i){
int x=X[i],k=K[i],y=x+k-1; l=0;
if(y<n) l=max(0,x*v+(F[y]==x?A[G[y]]+(G[y]>x):A[F[y]]+(F[y]>x)));
ans1^=l,ans2+=l;
}
printf("%lld %lld\n",ans1,ans2);
return 0;
}