1. 程式人生 > >【xsy2111】 【CODECHEF】Chef and Churus 分塊+樹狀數組

【xsy2111】 【CODECHEF】Chef and Churus 分塊+樹狀數組

class def 單點 codec bsp num 樹狀數組 修改 fin

題目大意:給你一個長度為$n$的數列$a_i$,定義$f_i=\sum_{j=l_i}^{r_i} num_j$。

有$m$個操作:

操作1:詢問一個區間$l,r$請你求出$\sum_{i=l}^{r} f_i$。

操作2:將$a_x$變成$y$。

題貌似正常做都不是很好做,考慮用一些奇奇怪怪的做法(比如說分塊)

考慮到此題數列在不斷地變化,我們考慮用樹狀數組來維護序列$a$,查詢$f_i$的值可以在$O(log n)$的時間內完成。

如果這麽做,單次詢問的復雜度是$O(n log n)$的,顯然不行。

我們令第$k$塊中包含有函數$f(kN),f(kN+1).......f(kN+(N-1))$。其中$N$是一個常數

設$sum[i][j]$表示第i塊中所有函數中數字$a_j$出現的次數。

設$ans[i]$表示第i塊所有函數之和。

顯然$ans[i]=\sum_{j=1}^{n} sum[i][j]\times num[j]$。

對於一個詢問的區間,我們顯然可以將其拆成盡可能多的塊+不超過$2N$個單點;

對於每個塊的塊的和,我們顯然可以在$O(1)$的復雜度內完成求值。

對於單點部分,我們直接查詢就可以了。

對於修改操作;

首先我們更新樹狀數組,然後根據$sum[i][X]$的值來更新$ans[i]$即可,時間復雜度是$O(log\ n+\sqrt{n})$。

總時間復雜度為$O(n^{1.5}\ log\ n)$

這次的分塊應該是編碼效率最高的一次了

 1 #include<bits/stdc++.h>
 2 #define M 100005
 3 #define N 360
 4 #define lowbit(x) ((x)&(-(x)))
 5 #define L unsigned long long
 6 int n,m,l[M]={0},r[M]={0};
 7 int sum[320][M]={0},num[M]={0},bel[M]={0};
 8 L ans[M]={0},a[M]={0};
 9 void add(int x,int k){for(int i=x;i<=n;i+=lowbit(i)) a[i]+=k;}
10 L Q(int x){L k=0; for(int i=x;i;i-=lowbit(i)) k+=a[i]; return k;} 11 int main(){ 12 scanf("%d",&n); 13 for(int i=1;i<=n;i++) bel[i]=(i+N-1)/N; 14 for(int i=1;i<=n;i++) scanf("%d",num+i),add(i,num[i]); 15 for(int i=1;i<=n;i++){ 16 scanf("%d%d",l+i,r+i); 17 ans[bel[i]]+=Q(r[i])-Q(l[i]-1); 18 sum[bel[i]][l[i]]++; sum[bel[i]][r[i]+1]--; 19 } 20 for(int x=1;x<=bel[n];x++) 21 for(int i=1;i<=n;i++) sum[x][i]+=sum[x][i-1]; 22 scanf("%d",&m); 23 while(m--){ 24 int op,X,Y;L res=0; scanf("%d%d%d",&op,&X,&Y); 25 if(op==1){ 26 for(int x=1;x<=bel[n];x++) 27 ans[x]+=1LL*sum[x][X]*(Y-num[X]); 28 add(X,Y-num[X]); num[X]=Y; 29 }else{ 30 if(bel[X]==bel[Y]){ 31 for(int i=X;i<=Y;i++) res+=Q(r[i])-Q(l[i]-1); 32 printf("%llu\n",res); 33 continue; 34 } 35 for(int x=bel[X]+1;x<bel[Y];x++) res+=ans[x]; 36 for(int i=X;bel[X]==bel[i];i++) res+=Q(r[i])-Q(l[i]-1); 37 for(int i=Y;bel[Y]==bel[i];i--) res+=Q(r[i])-Q(l[i]-1); 38 printf("%llu\n",res); 39 } 40 } 41 }

【xsy2111】 【CODECHEF】Chef and Churus 分塊+樹狀數組