POJ 3468 A Simple Problem with Integers

来源:互联网 发布:windows 10没远程桌面 编辑:程序博客网 时间:2024/06/15 12:39
A Simple Problem with Integers
Time Limit: 5000MS Memory Limit: 131072KTotal Submissions: 88754 Accepted: 27587Case Time Limit: 2000MS

Description

You have N integers, A1A2, ... , 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.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of AaAa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4

Sample Output

455915

Hint

The sums may exceed the range of 32-bit integers.

Source

POJ Monthly--2007.11.25, Yang Yi


【题目分析】

    线段树的基本操作 在加一个数时,并不是直接暴力更新而是打上标记。同时也要注意标记向下传的时间,否则效率会大大的降低。在poj上,我用C++提交同过了,但是用G++却TLE了。选择测试环境也是一种靠人品的东西。

#include <cstdio>#include <cstring>#include <string>#include <iostream>using namespace std;struct node{int l,r;long long sum,temp;}t[1400001];//初始的数组要开的大一些,防止爆炸 int data[400001];void build(int l,int r,int num){t[num].l=l; t[num].r=r;if (l==r){t[num].sum=data[l];return ;}else {int mid=(l+r)/2;build(l,mid,num*2);build(mid+1,r,num*2+1);t[num].sum=t[num*2].sum+t[num*2+1].sum;}return ;}void updata(int num)  //标记下传 ,不要和我说我的单词拼错了 我英语不好 {t[num*2].temp+=t[num].temp;//注意是+= t[num*2+1].temp+=t[num].temp;t[num*2].sum+=(t[num*2].r-t[num*2].l+1)*t[num].temp;t[num*2+1].sum+=(t[num*2+1].r-t[num*2+1].l+1)*t[num].temp;t[num].temp=0;}long long dosum(int l,int r,int num){if (t[num].r<l||t[num].l>r) return 0;if (t[num].l>=l&&t[num].r<=r) return t[num].sum;if (t[num].temp) updata(num);return dosum(l,r,num*2)+dosum(l,r,num*2+1);}void change(int l,int r,int add,int num){if (t[num].l>r||t[num].r<l) return ;if (t[num].l>=l&&t[num].r<=r){t[num].sum+=add*(t[num].r-t[num].l+1);t[num].temp+=add;return ;}if (t[num].temp) updata(num);int mid=l+r;change(l,r,add,num*2);change(l,r,add,num*2+1);t[num].sum=t[num*2].sum+t[num*2+1].sum;return;}int main(){int n,q;scanf("%d%d",&n,&q);for (int i=1;i<=n;++i) scanf("%d",&data[i]);build(1,n,1);while(q--){char ch;int a,b,c;cin>>ch;if (ch=='C'){cin>>a>>b>>c;change(a,b,c,1);}if (ch=='Q'){cin>>a>>b;cout<<dosum(a,b,1)<<endl;}}}


1 0