传送门 :
A Simple Problem with Integers
区间修改 + 区间查询
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.
You need to answer all Q commands in order. One answer in a line.
10 5 1 2 3 4 5 6 7 8 9 10 Q 4 4 Q 1 10 Q 2 4 C 3 6 3 Q 2 4Sample Output
4 55 9 15Hint
心路历程。。我觉得一张图可以体现:
不停的改啊改啊。。。
最后才发现 是** 输入格式出错了 应该是 %lld 我弄成了 %d
当个教训吧
#include<iostream>
#include<cstdio>
using namespace std;
long long int n,m,op,x,y,val;
long long int ans;
struct Tree{
int l;
int r;
long long int w;
long long int f;
}tree[200000*5+100];
void build(int k,int l,int r)
{
tree[k].l = l;
tree[k].r = r;
if(l == r)
{
scanf("%lld",&tree[k].w);
return ;
}
int m = (tree[k].l + tree[k].r )>>1;
build(k<<1,l,m);
build(k<<1|1,m+1,r);
tree[k].w = tree[k<<1].w + tree[k<<1|1].w;
}
void down(int k)
{
tree[k<<1].f +=tree[k].f;
tree[k<<1|1].f+= tree[k].f;
tree[k<<1].w += (tree[k<<1].r - tree[k<<1].l +1)*tree[k].f;
tree[k<<1|1].w += (tree[k<<1|1].r - tree[k<<1|1].l+1)*tree[k].f;
tree[k].f = 0;
}
void add(int k)
{
if(tree[k].l >=x&&tree[k].r<=y)
{
tree[k].w += (tree[k].r - tree[k].l + 1) * val;
tree[k].f += val;
return ;
}
if(tree[k].f ) down(k);
int m = (tree[k].l + tree[k].r)>>1;
if(x<=m) add(k<<1);
if(y>m) add(k<<1|1);
tree[k].w = tree[k<<1].w + tree[k<<1|1].w;
}
void ask(int k)
{
if(tree[k].l>=x&&tree[k].r<=y)
{
ans += tree[k].w;
return ;
}
if(tree[k].f) down(k);
int m = (tree[k].l + tree[k].r) >>1;
if(x<=m) ask(k<<1);
if(y>m) ask(k<<1|1);
}
int main()
{
scanf("%lld%lld",&n,&m);
build(1,1,n);
while(m--)
{
char op;
cin>>op;
scanf("%lld%lld",&x,&y);
if(op == 'C')
{
scanf("%lld",&val);
add(1);
}
else {
ans = 0;
ask(1);
printf("%lld\n",ans);
}
}
return 0;
}
ZKW 线段树
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 200000 + 5;
int n, M;
LL sum[maxn << 2], add[maxn << 2];
void build() {
M = 1;
while(M < (n + 2)) M <<= 1;
for (int i = 1; i <= n; i++) {
int x = M + i;
scanf("%lld", sum + x);
while(x >>= 1) sum[x] = sum[x << 1] + sum[x << 1 | 1];
}
}
void update(int l, int r, LL x) {
l += M - 1, r += M + 1;
int L = 0, R = 0;
for (int i = 1; l ^ r ^ 1; i <<= 1, l >>= 1, r >>= 1) {
sum[l] += L * x, sum[r] += R * x;
if(~l & 1) add[l ^ 1] += x, sum[l ^ 1] += i * x, L += i;
if(r & 1) add[r ^ 1] += x, sum[r ^ 1] += i * x, R += i;
}
sum[l] += L * x, sum[r] += R * x;
while(l >>= 1) sum[l] += x * (L + R);
}
LL query(int l, int r) {
l += M - 1, r += M + 1;
LL ans = 0;
int L = 0, R = 0;
for (int i = 1; l ^ r ^ 1; i <<= 1, l >>= 1, r >>= 1) {
ans += add[l] * L + add[r] * R;
if(~l & 1) ans += sum[l ^ 1], L += i;
if(r & 1) ans += sum[r ^ 1], R += i;
}
ans += add[l] * L + add[r] * R;
while(l >>= 1) ans += add[l] * (L + R);
return ans;
}
int main() {
scanf("%d", &n);
int q;
scanf("%d", &q);
build();
while(q--){
int a, b, c;
char op;
cin>>op;
scanf("%d%d", &a, &b);
if(op == 'C') {
scanf("%d", &c);
update(a, b, c);
}
else if(op == 'Q')
printf("%lld\n", query(a, b));
}
return 0;
}
呼。。。终于在睡觉之前 AC 了!
感谢昌神!!!