ACM-ICPC 2018 徐州赛区网络预赛 H. Ryuji doesn't want to study(树状数组)
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]前缀合,一个维护(n-i+1)*a[i]前缀和。
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <queue> #include <stack> #include <cstdlib> #include <iomanip> #include <cmath> #include <cassert> #include <ctime> #include <map> #include <set> using namespace std; #pragma comment(linker, "/stck:1024000000,1024000000") #pragma GCC diagnostic error "-std=c++11" #define lowbit(x) (x&(-x)) #define max(x,y) (x>=y?x:y) #define min(x,y) (x<=y?x:y) #define MAX 100000000000000000 #define MOD 1000000007 #define esp 1e-9 #define pi acos(-1.0) #define ei exp(1) #define PI 3.1415926535897932384626433832 #define ios() ios::sync_with_stdio(true) #define INF 0x3f3f3f3f typedef unsigned long long ll; ll sum[100006],n,m; ll pos[100005]; ll a[100005]; void add(int x,ll val){ for(int i=x;i;i-=lowbit(i)) sum[i]+=val; } ll query(int x){ ll ans=0; for(int i=x;i<=100004;i+=lowbit(i)) ans+=sum[i]; return ans; } void add_one(int x,ll val){ for(int i=x;i;i-=lowbit(i)) pos[i]+=val; } ll query_one(int x){ ll ans=0; for(int i=x;i<=100004;i+=lowbit(i)) ans+=pos[i]; return ans; } int main() { while(scanf("%lld%lld",&n,&m)!=EOF) { memset(sum,0,sizeof(sum)); memset(pos,0,sizeof(pos)); memset(a,0,sizeof(a)); for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); add(i,1ll*a[i]*(n-i+1)); add_one(i,a[i]); } while(m--){ ll op,x,y; scanf("%lld%lld%lld",&op,&x,&y); if(op==1) { ll l=query(x); ll r=query(y+1); ll u=query_one(x); ll d=query_one(y+1); //printf("%lld\n",u-d); printf("%lld\n",l-r-(1ll*(n-y)*(u-d))); } else{ add(x,1ll*(-1)*a[x]*(n-x+1)); add(x,1ll*(n-x+1)*y); add_one(x,1ll*(-1)*a[x]); a[x]=y; add_one(x,1ll*a[x]); } } } return 0; }