POJ 3468 A Simple Problem with Integers(線段樹區間操作)
題目的意思很簡單就是一個線段樹的區間的增加數字,與區間的查詢。
說一下,區間操作的題目第一次做啊,我瞎搞了一下,超時了啊。於是求助於嘯爺,嘯爺又是“苦心教導”啊。。感激不盡啊。。
一個區間當有更新的時候,先把區間上的總和更新一下,然後標記一下更新的多少,然後如果以後還會找到這個區間的時候,要把他所標記的那個數字傳到他的左右子樹中去。因為,這樣的話,只更新了這個區間。他的子區間能沒有發生過改變。所以要把他的標記給下面的然後抹去自己的標記。(說明它自己已經完成它對自己子樹的更新)。
Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 53175 | Accepted: 15899 | |
Case Time Limit: 2000MS |
Description
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.
Input
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.
Output
You need to answer all Q commands in order. One answer in a line.
Sample Input
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 4
Sample Output
4 55 9 15
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-7
#define M 10001000
//#define LL __LL64
#define LL long long
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
const LL maxn = 100100;
using namespace std;
struct node
{
LL sum;
LL add;
}f[4*maxn];
LL num[4*maxn];
void Bulid(LL l, LL r, LL site)
{
if(l == r)
{
f[site].sum = num[l];
f[site].add = 0;
return;
}
LL mid = (l+r)>>1;
Bulid(l, mid, site<<1);
Bulid(mid+1, r, site<<1|1);
f[site].add = 0;
f[site].sum = f[site<<1].sum+f[site<<1|1].sum;
}
void Updata(LL L, LL R, LL l, LL r, LL site, LL x)
{
if(L == l && R == r)
{
f[site].add += x;
f[site].sum += (r-l+1)*x;
return;
}
LL mid = (L+R)>>1;
if(f[site].add)//這裡如果不去掉標記的話,最後的賦值又可能會變小;因為沒更新左右的值;
{
Updata(L, mid, L, mid, site<<1, f[site].add);
Updata(mid+1, R, mid+1, R, site<<1|1, f[site].add);
f[site].add = 0;
}
if(r <= mid)
Updata(L, mid, l, r, site<<1, x);
else if(l > mid)
Updata(mid+1, R, l, r, site<<1|1, x);
else
{
Updata(L, mid, l, mid, site<<1, x);
Updata(mid+1, R, mid+1, r, site<<1|1, x);
}
f[site].sum = f[site<<1].sum+f[site<<1|1].sum;
}
node Qusery(LL L, LL R, LL l, LL r, LL site)
{
if(L == l && R == r)
{
return f[site];
}
LL mid = (L + R)>>1;
if(f[site].add)
{
Updata(L, mid, L, mid, site<<1, f[site].add);
Updata(mid+1, R, mid+1, R, site<<1|1, f[site].add);
f[site].add = 0;
}
if(r <= mid)
{
return Qusery(L, mid, l, r, site<<1);
}
else if(l > mid)
{
return Qusery(mid+1, R, l, r, site<<1|1);
}
node t1 = Qusery(L, mid, l, mid, site<<1);
node t2 = Qusery(mid+1, R, mid+1, r, site<<1|1);
t1.sum += t2.sum;
return t1;
}
int main()
{
LL n, m;
while(~scanf("%lld %lld",&n, &m))
{
for(LL i = 1; i <= n; i++)
scanf("%lld",&num[i]);
char str;
LL l, r, x;
Bulid(1, n, 1);
while(m--)
{
scanf("%*c%c",&str);
if(str == 'Q')
{
scanf("%lld %lld",&l, &r);
node temp;
temp = Qusery(1, n, l, r, 1);
printf("%lld\n",temp.sum);
}
else if(str == 'C')
{
scanf("%lld %lld %lld",&l, &r, &x);
Updata(1, n, l, r, 1, x);
}
}
}
return 0;
}
相關文章
- POJ 3468 A Simple Problem with Integers (線段樹 區間更新)
- POJ 3468 A Simple Problem with Integers (線段樹 區間共加)
- POJ 3468-A Simple Problem with Integers(區間更新線段樹)
- (poj3468)A Simple Problem with Integers(區間更新)
- 【poj3468】A Simple Problem with Integers
- POJ3468 A Simple Problem with Integers---樹狀陣列(區間問題)陣列
- bzoj3212: Pku3468 A Simple Problem with Integers(線段樹)
- POJ 3468 【區間修改+區間查詢 樹狀陣列 | 線段樹 | 分塊】陣列
- NC17383 A Simple Problem with Integers
- poj 3468 區間更新 整個區間加一個數和區間求和操作
- 線段樹(3)——區間操作疊加
- POJ 2528 Mayor's posters (線段樹 區間更新+離散化)
- POJ 2528 Mayor's posters (線段樹區間更新 + 離散化)
- POJ 2777-Count Color(線段樹-區間染色查詢)
- hihocoder 1078 線段樹的區間修改 (線段樹 區間更新 模板)
- POJ 3264-Balanced Lineup詳解(線段樹區間求值)
- 芻議線段樹 2 (區間修改,區間查詢)
- 線段樹維護區間等差數列
- HDU 1754 I Hate It (線段樹 區間最值)
- Java 演算法-區間求和I(線段樹)Java演算法
- HDU 1698 Just a Hook (線段樹區間更新)Hook
- Codeforces 52C (線段樹區間更新)
- 區間k小值(可持久化線段樹)持久化
- POJ 2991 Crane(線段樹+計算幾何)
- hdu 2665 可持久化線段樹求區間第K大值(函式式線段樹||主席樹)持久化函式
- 1082 線段樹練習 3 區間查詢與區間修改
- POJ 2777 Count Color 線段樹入門題
- 區間演算法題用線段樹可以秒解?演算法
- POJ 2828 Buy Tickets 線段樹入門(建樹稍微有點抽象)抽象
- Transformation HDU - 4578線段樹綜合操作ORM
- A - Yet Another Two Integers Problem ACMACM
- HDU1698 Just a Hook【線段樹基礎:區間修改+區間查詢】Hook
- poj 3237 樹鏈剖分(區間更新,區間查詢)
- POJ 2886 Who Gets the Most Candies?(線段樹+反素數)
- Codeforces 272C Dima and Staircase (線段樹區間更新 或 線性掃)AI
- POJ 2891 Strange Way to Express IntegersExpress
- 線~段~樹
- 線段樹