luoguP4231_三步必杀_差分
题意:N 个柱子排成一排,一开始每个柱子损伤度为0。接下来勇仪会进行M 次攻击,每次攻击可以用4个参数l,r ,s ,e 来描述:
表示这次攻击作用范围为第l个到第r 个之间所有的柱子(包含l ,r ),对第一个柱子的伤害为s ,对最后一个柱子的伤害为e 。
攻击产生的伤害值是一个等差数列。若l=1 ,r=5 ,s=2 ,e=10 ,则对第1~5个柱子分别产生2,4,6,8,10的伤害。
鬼族们需要的是所有攻击完成之后每个柱子的损伤度。
分析:等差数列差分后相当于区间加,再套一个差分可解。
差分套差分求两遍前缀和就是原数组。注意有几个需要差分的单点修改。
代码:
1 // luogu-judger-enable-o2 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 using namespace std; 6 #define LL long long 7 #define N 10000002 8 LL c[N]; 9 LL n,m; 10 void read(LL &x){ 11 int f=1;x=0;char s=getchar(); 12 while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();} 13 while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}x*=f; 14 } 15 int main(){ 16 read(n),read(m); 17 LL l,r,s,t; 18 register int i; 19 for(i=1;i<=m;i++){ 20 read(l),read(r),read(s),read(t); 21 if(l==r){ 22 c[l]+=s;c[l+1]-=2*s;c[l+2]+=s;continue; 23 } 24 LL d=(t-s)/(r-l); 25 c[l]+=s;c[l+1]-=(s-d);c[r+1]-=((r-l)*d+s+d);c[r+2]+=((r-l)*d+s); 26 } 27 for(i=1;i<=n;i++){ 28 c[i]+=c[i-1]; 29 } 30 LL mx=0,sum=0; 31 for(i=1;i<=n;i++){ 32 c[i]+=c[i-1]; 33 mx=max(mx,c[i]); 34 sum^=c[i]; 35 } 36 printf("%lld %lld",sum,mx); 37 } 38