標籤:net lan printf amp 說明 define nbsp include 資料規模
P3368 【模板】樹狀數組 2
題目描述
如題,已知一個數列,你需要進行下面兩種操作:
1.將某區間每一個數數加上x
2.求出某一個數的和
輸入輸出格式輸入格式:
第一行包含兩個整數N、M,分別表示該數列數位個數和操作的總個數。
第二行包含N個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。
接下來M行每行包含2或4個整數,表示一個操作,具體如下:
操作1: 格式:1 x y k 含義:將區間[x,y]內每個數加上k
操作2: 格式:2 x 含義:輸出第x個數的值
輸出格式:
輸出包含若干行整數,即為所有操作2的結果。
輸入輸出範例輸入範例#1:
5 51 5 4 2 31 2 4 22 31 1 5 -11 3 5 72 4
輸出範例#1:
610
說明
時空限制:1000ms,128M
資料規模:
對於30%的資料:N<=8,M<=10
對於70%的資料:N<=10000,M<=10000
對於100%的資料:N<=500000,M<=500000
範例說明:
故輸出結果為6、10
----------------------------------------------------------------------------------------------
推一篇部落格:http://blog.csdn.net/qq_21841245/article/details/43956633
最主要的做法其實是差分數組
用樹狀數組維護數組的首碼和只是為了達到最佳化時間複雜度的目的
存板子:
1 #include<stdio.h> 2 #include<string.h> 3 #define maxn 500010 4 int delta[maxn],a[maxn],n,m; 5 int read(); 6 int lowbit(int); 7 void add(int,int); 8 int find(int); 9 int main(){10 n=read(),m=read();11 for(int i=1;i<=n;i++) a[i]=read();12 for(int i=1;i<=m;i++){13 int o=read();14 if(o==1){15 int x=read(),y=read(),k=read();16 add(x,k);add(y+1,-k);17 }18 else{19 int x=read();20 int ans=find(x)+a[x];21 printf("%d\n",ans);22 }23 }24 return 0;25 }26 int find(int x){27 int SUM=0;28 while(x>0){29 SUM+=delta[x];30 x-=lowbit(x);31 }32 return SUM;33 }34 void add(int x,int k){35 while(x<=n){36 delta[x]+=k;37 x+=lowbit(x);38 }39 }40 int lowbit(int x){41 return x&-x;42 }43 int read(){44 int ans=0,f=1;char c=getchar();45 while(‘0‘>c||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}46 while(‘0‘<=c&&c<=‘9‘)ans=ans*10+c-48,c=getchar();return ans*f;47 }區間修改+單點查詢
洛穀 P3368 【模板】樹狀數組 2 如題(區間修改+單點查詢)