Luogu1438 无聊的数列(线段树)

传送门:https://www.luogu.org/problem/P1438

线段树板子题,

真的裸,

数学题真好磕

如果看到加上等差数列还想不到差分的话我也没话可说了……

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N = 100050;
 4 typedef long long ll;
 5 #define fr(i,n) for(int i = 1; i <= n; i++)
 6 #define pr(n) printf("%d
",n)
 7 inline int read() {
 8     char c = getchar();
 9     int x = 0, f = 1;
10     while(c < '0' || c > '9') {
11         if(c == '-') f = -1;
12         c = getchar();
13     }
14     while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
15     return x * f;
16 }
17 int n,m;
18 int s[N], tag[N<<2];
19 int sum[N<<2]; 
20 
21 void pushup(int u) { sum[u] = sum[u << 1] + sum[u << 1 | 1]; }
22 
23 void buildTree(int u, int uL, int uR)
24 {
25     if(uL == uR) {
26         scanf("%lld",&sum[u]);
27         return ;
28     }
29     int mid = (uL + uR) >> 1;
30     buildTree(u << 1, uL,mid);
31     buildTree(u << 1 | 1, mid + 1,uR);
32     pushup(u);
33 }
34 
35 void update(int u, int uL, int uR, int mx)
36 {
37     tag[u] += mx;  
38     sum[u] += (ll)(uR - uL + 1) * mx;
39 }
40 
41 void pushdown(int u, int uL, int uR)
42 {
43     if(tag[u]){
44         int mid = (uL + uR) >> 1;
45         update(u << 1, uL, mid, tag[u]);
46         update(u << 1|1, mid + 1,uR, tag[u]);
47         tag[u] = 0; 
48     }
49 }
50 
51 void modify(int u, int uL, int uR, int mL, int mR, int mx)
52 {   
53     if(mL <= uL && mR >= uR) {
54         update(u,uL,uR,mx);
55         return;
56     }
57     pushdown(u,uL,uR);
58     int mid = (uL + uR) >> 1;
59     if(mL <= mid) modify(u << 1, uL, mid, mL, mR, mx); 
60     if(mid < mR) modify(u << 1 | 1, mid + 1, uR, mL,mR, mx);
61     pushup(u); 
62 }
63 
64 ll query(int u, int uL, int uR, int mL, int mR)
65 {
66     if(mL <= uL && mR >= uR)  return sum[u];
67     pushdown(u, uL, uR);
68     int mid = (uL + uR) >> 1;
69     ll ans = 0;
70     if(mL <= mid) ans += query(u << 1, uL, mid, mL, mR); 
71     if(mid < mR) ans += query(u << 1 | 1, mid + 1, uR, mL, mR);
72     return ans;
73 }
74 //------------------------------------------------以上是板子----------------------------------
75 int main()
76 {
77   int l,r,opt,k,d,n,m,aim;
78   n = read();m = read();
79   fr(i,n) s[i] = read();
80   while(m--){
81       opt = read();
82       if(opt == 1){ //1 L R K D:给出一个长度等于R-L+1的等差数列,首项为K,公差为D,并将它对应加到a[L]~a[R]的每一个数上。
83            l = read(),r = read(),k = read(),d = read();
84            modify(1,1,n,l,l,k);
85            if(r > l) modify(1,1,n,l+1,r,d);
86            int N = r - l + 1;
87            if(r != n) modify(1,1,n,r+1,r+1,-(k+(N-1)*d));
88       }
89     else {
90         aim = read();
91         pr(s[aim] + query(1,1,n,1,aim));
92     }  
93   }
94   return 0;
95 }
原文地址:https://www.cnblogs.com/phemiku/p/11630562.html