ACM-ICPC 2018 徐州赛区网络预赛 H. Ryuji doesn't want to study (线段树)
Ryuji is not a good student, and he doesn't want to study. But there are n books he should learn, each book has its knowledge a[i]a[i].
Unfortunately, the longer he learns, the fewer he gets.
That means, if he reads books from ll to rr, he will get a[l] \times L + a[l+1] \times (L-1) + \cdots + a[r-1] \times 2 + a[r]a[l]×L+a[l+1]×(L−1)+⋯+a[r−1]×2+a[r] (LL is the length of [ ll, rr ] that equals to r - l + 1r−l+1).
Now Ryuji has qq questions, you should answer him:
11. If the question type is 11, you should answer how much knowledge he will get after he reads books [ ll, rr ].
22. If the question type is 22, Ryuji will change the ith book's knowledge to a new value.
Input
First line contains two integers nn and qq (nn, q \le 100000q≤100000).
The next line contains n integers represent a[i]( a[i] \le 1e9)a[i](a[i]≤1e9) .
Then in next qq line each line contains three integers aa, bb, cc, if a = 1a=1, it means question type is 11, and bb, ccrepresents [ ll , rr ]. if a = 2a=2 , it means question type is 22 , and bb, cc means Ryuji changes the bth book' knowledge to cc
Output
For each question, output one line with one integer represent the answer.
样例输入
5 3
1 2 3 4 5 1 1 3 2 5 0 1 4 5
样例输出
10
5
题目链接:
https://nanti.jisuanke.com/t/31460
题目大意:
给你一个数列a[1..n],多次求对于[i..j]区间,a[i]*L+a[i+1]*(L-1)+...+a[j]*1,其中L是区间长度(j-i+1)。
线段树水题。
对该数列建立线段树。每个节点维护两个值sum和tri。sum是区间和,tri是区间三角和(即题目中所要求的和)。适当地改动一下操作,就是一个简单的单点修改,区间查询的线段树问题。
由于是在区域赛预赛中做出来的,还是写个博客纪念一下吧。^_^
#include<cstdio> #include<cmath> using namespace std; const int maxn=100000; struct ttree { int l,r; long long sum; long long tri; }; ttree tree[maxn*4+10]; void pushup(int x) { if(tree[x].l==tree[x].r) return; tree[x].sum=tree[x*2].sum+tree[x*2+1].sum; tree[x].tri=tree[x*2].tri+tree[x*2+1].tri+ tree[x*2].sum*(tree[x*2+1].r-tree[x*2+1].l+1); } void build(int x,int l,int r) { tree[x].l=l; tree[x].r=r; if(l==r) { scanf("%lld",&tree[x].sum); tree[x].tri=tree[x].sum; } else { int mid=(l+r)/2; build(x*2,l,mid); build(x*2+1,mid+1,r); pushup(x); } } void modify(int x,int pos,int val) { if(tree[x].l==tree[x].r) { tree[x].sum=tree[x].tri=val; return; } int mid=(tree[x].l+tree[x].r)/2; if(pos<=mid) modify(x*2,pos,val); else modify(x*2+1,pos,val); pushup(x); } long long query(int x,int l,int r) { if(l<=tree[x].l&&r>=tree[x].r) return tree[x].sum*(r-tree[x].r)+tree[x].tri; long long ret=0; int mid=(tree[x].l+tree[x].r)/2; if(l<=mid) ret+=query(x*2,l,r); if(r>mid) ret+=query(x*2+1,l,r); return ret; } int main() { int n,q; scanf("%d%d",&n,&q); build(1,1,n); int a,b,c; while(q--) { scanf("%d%d%d",&a,&b,&c); if(a==1) { printf("%lld\n",query(1,b,c)); } else { modify(1,b,c); } } return 0; }