3155: Preprefix sum

3155: Preprefix sum

https://www.lydsy.com/JudgeOnline/problem.php?id=3155

分析:

  区间修改,区间查询,线段树就好了。

  然后,这题有树状数组!

代码:

线段树620ms

 1 /*
 2 一个数修改影响后面的数,使后面的数都增加或者减少多少,所以线段树维护区间和,区间修改
 3 */
 4 #include<bits/stdc++.h>
 5 using namespace std;
 6 typedef long long LL;
 7
 8 inline int read() {
 9     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch==‘-‘)f=-1;
10     for (;isdigit(ch);ch=getchar())x=x*10+ch-‘0‘;return x*f;
11 }
12
13 const int N = 100010;
14
15 #define Root 1,n,1
16 #define lson l,mid,rt<<1
17 #define rson mid+1,r,rt<<1|1
18
19 LL sum[N<<2],tag[N<<2],a[N],s[N];
20 void pushup(int rt) {
21     sum[rt] = sum[rt<<1] + sum[rt<<1|1];
22 }
23 void pushdown(int rt,int len) {
24     if (tag[rt]) {
25         tag[rt<<1] += tag[rt]; sum[rt<<1] += tag[rt] * 1ll * (len-len/2);
26         tag[rt<<1|1] += tag[rt]; sum[rt<<1|1] += tag[rt] * 1ll * (len/2);
27         tag[rt] = 0; //--忘记1
28     }
29 }
30 void build(int l,int r,int rt) {
31     if (l == r) {
32         sum[rt] = s[l];
33         return ;
34     }
35     int mid = (l + r) >> 1;
36     build(lson);
37     build(rson);
38     pushup(rt);
39 }
40 void update(int l,int r,int rt,int L,int R,LL val) {
41     if (L <= l && r <= R) {
42         sum[rt] += val*1ll*(r-l+1);tag[rt] += val;
43         return ;
44     }
45     int mid = (l + r) >> 1;
46     pushdown(rt,r-l+1);
47     if (L <= mid) update(lson,L,R,val);
48     if (R > mid)  update(rson,L,R,val);
49     pushup(rt);
50 }
51 LL query(int l,int r,int rt,int L,int R) {
52     if (L <= l && r <= R) {
53         return sum[rt];
54     }
55     int mid = (l + r) >> 1;
56     LL res = 0;
57     pushdown(rt,r-l+1);
58     if (L <= mid) res += query(lson,L,R);
59     if (R > mid)  res += query(rson,L,R);
60     return res;//--忘记2
61 }
62 int main() {
63     int n = read(),m = read();
64     for (int t,i=1; i<=n; ++i) {
65         a[i] = read();
66         s[i] = s[i-1] + a[i];
67     }
68     build(Root);
69     char opt[10];
70     while (m--) {
71         scanf("%s",opt);
72         if (opt[0]==‘Q‘) {
73             int p = read();
74             printf("%lld\n",query(Root,1,p));
75         }
76         else {
77             int p = read(); LL v = read();
78             update(Root,p,n,v-a[p]);
79             a[p] = v;
80         }
81     }
82     return 0;
83 }

树状数组392ms

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4
 5 inline int read() {
 6     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch==‘-‘)f=-1;
 7     for (;isdigit(ch);ch=getchar())x=x*10+ch-‘0‘;return x*f;
 8 }
 9
10 const int N = 100010;
11 LL a[N];
12
13 struct BIT{
14     int n;LL c1[N],c2[N];
15     void update(int p,LL v) {
16         for (int i=p; i<=n; i+=(i&(-i))) c1[i] += v,c2[i] += 1ll*p*v; // long long
17     }
18     LL query(int p) {
19         LL ans = 0;
20         for (int i=p; i; i-=(i&(-i))) ans += 1ll*(p+1)*c1[i]-c2[i];
21         return ans;
22     }
23 }bit;
24
25 int main() {
26     int n = read(),m = read();
27     bit.n = n;  // ---
28     for (int i=1; i<=n; ++i) {
29         a[i] = read();
30         bit.update(i,a[i]);
31     }
32     char opt[10];
33     while (m--) {
34         scanf("%s",opt);
35         if (opt[0]==‘Q‘) {
36             int p = read();
37             printf("%lld\n",bit.query(p));
38         }
39         else {
40             int p = read(); LL v = read();
41             bit.update(p,v-a[p]);
42             a[p] = v;
43         }
44     }
45     return 0;
46 }

原文地址:https://www.cnblogs.com/mjtcn/p/9281177.html

时间: 2024-08-30 01:53:19

3155: Preprefix sum的相关文章

BZOJ 3155 Preprefix sum

两个BIT. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 100050 using namespace std; long long n,m,x,y,t[maxn][3],a[maxn]; char s[12]; long long lowbit(long long x) {return (x&(-x));} void m

[bzoj3155]Preprefix sum(树状数组)

3155: Preprefix sum Time Limit: 1 Sec  Memory Limit: 512 MBSubmit: 1183  Solved: 546[Submit][Status][Discuss] Description Input 第一行给出两个整数N,M.分别表示序列长度和操作个数 接下来一行有N个数,即给定的序列a1,a2,....an 接下来M行,每行对应一个操作,格式见题目描述 Output 对于每个询问操作,输出一行,表示所询问的SSi的值. Sample In

差分+树状数组【p4868】Preprefix sum

Description 前缀和(prefix sum)\(S_i=\sum_{k=1}^i a_i\). 前前缀和(preprefix sum) 则把\(S_i\)作为原序列再进行前缀和.记再次求得前缀和第i个是\(SS_i\) 给一个长度n的序列\(a_1, a_2, \cdots, a_n\)有两种操作: Modify i x:把\(a_i\)改成\(x\): Query i:查询\(SS_i\) Input 第一行给出两个整数N,M.分别表示序列长度和操作个数 接下来一行有N个数,即给定的

BZOJ3155: Preprefix sum

题解: 写过树状数组搞区间修改和区间求和的就可以秒出吧... 代码: 1 #include<cstdio> 2 3 #include<cstdlib> 4 5 #include<cmath> 6 7 #include<cstring> 8 9 #include<algorithm> 10 11 #include<iostream> 12 13 #include<vector> 14 15 #include<map&g

BZOJ3155Preprefix sum

3155: Preprefix sum Time Limit: 1 Sec  Memory Limit: 512 MBSubmit: 1288  Solved: 588 Description Input 第一行给出两个整数N,M.分别表示序列长度和操作个数 接下来一行有N个数,即给定的序列a1,a2,....an 接下来M行,每行对应一个操作,格式见题目描述 Output 对于每个询问操作,输出一行,表示所询问的SSi的值. Sample Input 5 3 1 2 3 4 5 Query 5

大神刷题表

9月27日 后缀数组:[wikioi3160]最长公共子串 dp:NOIP2001统计单词个数 后缀自动机:[spoj1812]Longest Common Substring II [wikioi3160]最长公共子串 [spoj7258]Lexicographical Substring Search 扫描线+set:[poj2932]Coneology 扫描线+set+树上删边游戏:[FJOI2013]圆形游戏 结论:[bzoj3706][FJ2014集训]反色刷 最小环:[poj1734

树状数组(下)

树状数组(下) 目录 树状数组(下) 应用 逆序对 康托展开 逆康托展开 RMQ问题树状数组解法 查询第k小 习题 Preprefix sum 在树状数组(上)中我提到了树状数组的基本操作与变式,现在来看看它的实际应用和一些题目. 应用 逆序对 设\(a\)为一个有\(n\)个数字的有序集(\(n>1\)),其中所有数字各不相同. 如果存在正整数\(i\),\(j\)使得\(1\leqslant i<j\leqslant n\)且\(a[i]>a[j]\), 则有序对\((a[i],a[

POJ 3155 Hard Life(最大密度子图)

POJ 3155 Hard Life 题目链接 最大密度子图模板题 代码: #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; const int MAXNODE = 1105; const int MAXEDGE = 100005; typedef double Type; const Type INF = 1e15;

POJ 3155 最大密度子图

链接: http://poj.org/problem?id=3155 题解: 要最大化下式: 可以用二分求解以下分数规划问题: 也就是最大化: 设子图为G'=(V', E').如果边(u,v)∈E',那么必有u,v属于V'.把点权设为负值的话,问题可以转换为求最大权闭合图(POJ 2987 Firing). 又因为点固定时,边越多越好.所以转换思路,不是边E'决定点集V',而应该反过来.当选定点集V'后,V'内部两两之间能构成的边就是最佳的E'.那么由V'发出的,不在E'内部的那些边构成了一个割