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]a[i].
Unfortunately, the longer he learns, the fewer he gets.
That means, if he reads books from lll to rrr, he will get a[l]×L+a[l+1]×(L−1)+⋯+a[r−1]×2+a[r]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] (LLL is the length of [ lll, rrr ] that equals to r−l+1r - l + 1r−l+1).
Now Ryuji has qqq questions, you should answer him:
111. If the question type is 111, you should answer how much knowledge he will get after he reads books [ lll, rrr ].
222. If the question type is 222, Ryuji will change the ith book's knowledge to a new value.
Input
First line contains two integers nnn and qqq (nnn, q≤100000q \le 100000q≤100000).
The next line contains n integers represent a[i](a[i]≤1e9)a[i]( a[i] \le 1e9)a[i](a[i]≤1e9) .
Then in next qqq line each line contains three integers aaa, bbb, ccc, if a=1a = 1a=1, it means question type is 111, and bbb, ccc represents [ lll , rrr ]. if a=2a = 2a=2 , it means question type is 222 , and bbb, ccc means Ryuji changes the bth book' knowledge to ccc
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 8
題目來源
將a[i]*(r-i+1)化成a[i]*(r+1)-a[i] 然後建兩個二叉樹, 一個維護區間和, 一個維護字首區間和。
程式碼如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn=100005;
long long int a[maxn];
long long int t1[maxn<<2];
long long int t2[maxn<<2];
int n,q;
void pushup (int re,long long int* t)
{
t[re]=t[re<<1]+t[re<<1|1];
}
void build1 (int l,int r,int re,long long int* t)
{
if(l==r)
{
t[re]=a[l];
return;
}
int mid=(l+r)>>1;
build1 (l,mid,re<<1,t);
build1 (mid+1,r,re<<1|1,t);
pushup (re,t);
}
void build2 (int l,int r,int re,long long int* t)
{
if(l==r)
{
t[re]=a[l]*l;
return;
}
int mid=(l+r)>>1;
build2 (l,mid,re<<1,t);
build2 (mid+1,r,re<<1|1,t);
pushup (re,t);
}
void update1 (int l,int r,int re,int loc,long long int data,long long int* t)
{
if(l==r)
{
t[re]=data;
return;
}
int mid=(l+r)>>1;
if(mid>=loc)
update1 (l,mid,re<<1,loc,data,t);
else
update1 (mid+1,r,re<<1|1,loc,data,t);
pushup(re,t);
}
void update2 (int l,int r,int re,int loc,long long int data,long long int* t)
{
if(l==r)
{
t[re]=data*l;
return;
}
int mid=(l+r)>>1;
if(mid>=loc)
update2 (l,mid,re<<1,loc,data,t);
else
update2 (mid+1,r,re<<1|1,loc,data,t);
pushup(re,t);
}
long long int query (int l,int r,int re,int left,int right,long long int* t)
{
if(l>=left&&r<=right)
return t[re];
long long int ans=0;
int mid=(l+r)>>1;
if(mid>=left)
ans+=query (l,mid,re<<1,left,right,t);
if(mid<right)
ans+=query (mid+1,r,re<<1|1,left,right,t);
return ans;
}
int main()
{
scanf("%d%d",&n,&q);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
build1 (1,n,1,t1);
build2 (1,n,1,t2);
while (q--)
{
int op;
long long int x,y;
scanf("%d%lld%lld",&op,&x,&y);
if(op==1)
{
long long int sum=(y+1)*query(1,n,1,x,y,t1)-query(1,n,1,x,y,t2);
printf("%lld\n",sum);
}
else
{
update1(1,n,1,x,y,t1);
update2(1,n,1,x,y,t2);
}
}
return 0;
}