2015 UESTC 数据结构专题B题 秋实大哥与花 线段树 区间加,区间查询和
B - 秋实大哥与花
Time Limit: 1 Sec Memory Limit: 256 MB
题目连接
http://acm.uestc.edu.cn/#/contest/show/59Description
秋实大哥是一个儒雅之人,昼听笙歌夜醉眠,若非月下即花前。
所以秋实大哥精心照料了很多花朵。现在所有的花朵排成了一行,每朵花有一个愉悦值。
秋实大哥每天要对着某一段连续的花朵歌唱,然后这些花朵的愉悦值都会增加一个相同的值v(v可能为负)。
同时他想知道每次他唱完歌后这一段连续的花朵的愉悦值总和是多少。
Input
第一行有一个整数n,表示花朵的总数目。
第二行包含n个整数ai,表示第i朵花初始的愉悦值。
第三行包含一个整数m,表示秋实大哥唱了m天的歌。
接下来m行,每行包含三个整数l r v,表示秋实大哥对着[l,r]这个区间内的花朵歌唱,每朵花的愉悦值增加了v。
1≤n,m,ai,|v|≤100000,1≤l≤r≤n。
第二行包含n个整数ai,表示第i朵花初始的愉悦值。
第三行包含一个整数m,表示秋实大哥唱了m天的歌。
接下来m行,每行包含三个整数l r v,表示秋实大哥对着[l,r]这个区间内的花朵歌唱,每朵花的愉悦值增加了v。
1≤n,m,ai,|v|≤100000,1≤l≤r≤n。
Output
输出共m行,第i行表示秋实大哥完成第i天的歌唱后,那一段花朵的愉悦值总和。
Sample Input
3
0 0 0
3
1 2 1
1 2 -1
1 3 1
0 0 0
3
1 2 1
1 2 -1
1 3 1
Sample Output
2
0
3
0
3
HINT
题意
题解:
啊,裸题嘛,随便搞搞就好了代码:
//qscqesze #include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <vector> #include <sstream> #include <queue> #include <typeinfo> #include <fstream> #include <map> #include <stack> #define LL(x) (x<<1) #define RR(x) (x<<1|1) #define MID(a,b) (a+((b-a)>>1)) const int N=500000; typedef long long LL; typedef long long ll; using namespace std; //freopen("D.in","r",stdin); //freopen("D.out","w",stdout); #define sspeed ios_base::sync_with_stdio(0);cin.tie(0) #define maxn 200001 #define mod 10007 #define eps 1e-9 //const int inf=0x7fffffff; //无限大 const int inf=0x3f3f3f3f; /* int buf[10]; inline void write(int i) { int p = 0;if(i == 0) p++; else while(i) {buf[p++] = i % 10;i /= 10;} for(int j = p-1; j >=0; j--) putchar('0' + buf[j]); printf("\n"); } */ //************************************************************************************** inline ll read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct node { int lft,rht; LL sum,add; int mid(){return MID(lft,rht);} void fun(LL tmp) { add+=tmp; sum+=(rht-lft+1)*tmp; } }; int y[N]; struct Segtree { node tree[N*4]; void relax(int ind) { if(tree[ind].add) { tree[LL(ind)].fun(tree[ind].add); tree[RR(ind)].fun(tree[ind].add); tree[ind].add=0; } } void build(int lft,int rht,int ind) { tree[ind].lft=lft; tree[ind].rht=rht; tree[ind].sum=0; tree[ind].add=0; if(lft==rht) tree[ind].sum=y[lft]; else { int mid=tree[ind].mid(); build(lft,mid,LL(ind)); build(mid+1,rht,RR(ind)); tree[ind].sum=tree[LL(ind)].sum+tree[RR(ind)].sum; } } void updata(int st,int ed,int ind,int add) { int lft=tree[ind].lft,rht=tree[ind].rht; if(st<=lft&&rht<=ed) tree[ind].fun(add); else { relax(ind); int mid=tree[ind].mid(); if(st<=mid) updata(st,ed,LL(ind),add); if(ed> mid) updata(st,ed,RR(ind),add); tree[ind].sum=tree[LL(ind)].sum+tree[RR(ind)].sum; } } LL query(int st,int ed,int ind) { int lft=tree[ind].lft,rht=tree[ind].rht; if(st<=lft&&rht<=ed) return tree[ind].sum; else { relax(ind); int mid=tree[ind].mid(); LL sum1=0,sum2=0; if(st<=mid) sum1=query(st,ed,LL(ind)); if(ed> mid) sum2=query(st,ed,RR(ind)); return sum1+sum2; } } }seg; int main() { int n,m; while(scanf("%d",&n)!=EOF) { char str[5]; int a,b,c; for(int i=1;i<=n;i++) scanf("%d",&y[i]); seg.build(1,n,1); scanf("%d",&m); while(m--) { scanf("%d%d%d",&a,&b,&c); seg.updata(a,b,1,c); printf("%lld\n",seg.query(a,b,1)); } } return 0; }