Luogu P4231【三步必杀】
Kirisame_Marisa_ · · 题解
传送门:P4231
差分好题。
由于增加的是等差数列,所以可求相邻两项的差。将差设为
接下来设原数组为
i 1 2 3 4 5 6 7 ...
a 0 2 7 12 17 0 0 ...
b 0 2 5 5 5 -17 0 ...
可以发现,每次修改转化成了
其实到这里已经距离正解很近了。通过差分的特性,我们可以发现:
i 1 2 3 4 5 6 7 ...
a 0 2 7 12 17 0 0 ...
b 0 2 5 5 5 -17 0 ...
c 0 2 3 0 0 -22 17 ...
可以发现,原先的
那么如何通过
通过差分的定义,可以知道
容易发现
现在探究一下修改操作的一般情况,对于每次修改操作,都有如下变化:
i l-1 l l+1 l+2 ... r-1 r r+1 r+2 ...
a 0 s s+d s+2d ... e-d e 0 0 ...
b 0 s d d ... d d -e 0 ...
c 0 s d-s 0 ... 0 0 -e-d e ...
所以对于每次修改
最后统计答案时对数组
总时间复杂度:
注意值域long long。
Code:(我知道有的人看这么久其实只想看这个)
#include<bits/stdc++.h>
using namespace std;
inline long long fi()
{
register long long x=0;register char ch;
while(!isdigit(ch=getchar()));x=ch-48;
while(isdigit(ch=getchar()))x=x*10+ch-48;
return x;
}
long long n,m,l,r,s,e,d;
long long b[10000005];
int main()
{
n=fi();m=fi();
while(m--)
{
l=fi();r=fi();s=fi();e=fi();
d=(e-s)/(r-l);
b[l]+=s;
b[l+1]+=(d-s);
b[r+1]+=(-e-d);
b[r+2]+=e;
}
register long long ans1=0,ans2=0,tmp=0;
for(register int i=1;i<=n;++i)b[i]+=b[i-1];
for(register int i=1;i<=n;++i)
{
tmp+=b[i];
ans1^=tmp;
ans2=max(ans2,tmp);
}
cout<<ans1<<" "<<ans2;
return 0;
}