luogu P4231 三步必杀 差分数组+差分数组

P4231 三步必杀 差分数组+差分数组
一看等差数列思路就往奇怪的地方去了……
突然想到常数列前缀和就是等差
又想到上周D1T1后缀和的后缀和就是类似的东西
所以在题目明显暗示差分的情况下做一下差分的差分
然后由于最后求前缀和只需要1~n所以就只需要每次在差分数组上修改就可以了
也只需要这一个数组
然后n<=1e7……彻底维护不了前缀和了 (本来还想用树状数组的……)
区间异或和最大值都扫一遍就行
证明具体描述不清楚 拿差分推一遍两遍就行
Code:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 #define rep(i,a,n) for(int i = a;i <= n;i++)
 6 #define per(i,n,a) for(int i = n;i >= a;i--)
 7 #define ms(a,b) memset(a,b,sizeof a)
 8 #define inf 2147483647
 9 using namespace std;
10 typedef long long ll;
11 ll read() {
12     ll as = 0,fu = 1;
13     char c = getchar();
14     while(c < '0' || c > '9') {
15         if(c == '-') fu = -1;
16         c = getchar();
17     }
18     while(c >= '0' && c <= '9') {
19         as = as * 10 + c - '0';
20         c = getchar();
21     }
22     return as * fu;
23 }
24 const int N = 10000005;
25 //head
26 ll n,m;
27 ll ccf[N];
28 ll cf,ori;
29 ll maxx,XOR;
30 int main() {
31     n = read();
32     m = read();
33     rep(i,1,m) {
34     int l = read();
35     int r = read();
36     ll s = read();
37     ll e = read();
38     ll d = (e-s) / (r-l);
39     //gong_cha
40     ccf[l] += s;
41     ccf[l+1] += d-s;
42     ccf[r+1] += (-d-e);
43     ccf[r+2] += e;
44     }
45     rep(i,1,n) {
46     cf += ccf[i];
47     ori += cf;
48     maxx = max(maxx,ori);
49     XOR ^= ori;
50     }
51     printf("%lld %lld\n",XOR,maxx);
52     return 0;
53 }

 

posted @ 2018-09-21 17:29  白怀潇  阅读(217)  评论(0编辑  收藏  举报