poj3468區間加減查找——樹狀數組區間修改查詢
阿新 • • 發佈:2018-02-11
兩個 區間和 urn void pos sharp space scan 個數
題目:http://poj.org/problem?id=3468
增加一個更改量數組,施以差值用法則區間修改變為單位置修改;
利用公式可通過樹狀數組維護兩個數組:f與g而直接求出區間和。
代碼如下:
#include<iostream> #include<cstdio> using namespace std; long long n,q,a[100005]/*,b[100005],bg[100005]*/,l,r,ad; long long f[100005],g[100005],sum[100005];//f[x]為更改量 char dc; long long query(long long x) { long long k=x; long long summ=0; for(;x;x-=x&-x) summ+=f[x]; long long s2=0; x=k; for(;x;x-=x&-x) s2+=g[x]; return (k+1)*summ-s2; } void add(long long x,long long y)//x單位置增加y { long long k=x; for(x;x<=n;x+=x&-x) f[x]+=y,g[x]+=k*y; } int main() { scanf("%lld%lld",&n,&q); for(long long i=1;i<=n;i++) { scanf("%lld",&sum[i]); sum[i]+=sum[i-1]; // b[i]=a[i]-a[i-1]; // for(int j=i-(i&-i)+1;j<=i;j++)f[i]+=b[j];//差值 // bg[i]=i*b[i]; // for(int j=i-(i&-i)+1;j<=i;j++)g[i]+=bg[j]; // g[i]=i*f[i]; } for(long long i=1;i<=q;i++) { scanf(" %c",&dc); if(dc==‘C‘) { scanf("%lld%lld%lld",&l,&r,&ad); add(l,ad);add(r+1,-ad); } if(dc==‘Q‘) { scanf("%lld%lld",&l,&r); long long ans=query(r)+sum[r]-query(l-1)-sum[l-1]; printf("%lld\n",ans); } } return 0; }
poj3468區間加減查找——樹狀數組區間修改查詢