1. 程式人生 > >分塊試水--CODEVS5037 線段樹練習4加強版

分塊試水--CODEVS5037 線段樹練習4加強版

git 感覺 clas closed == splay hid pos 修改

感覺這才算入門題吧。。前面那些線段樹練習,改幾個字符就過了一定要搞成幾道題。。

n<=2e5的數列,給常數K<=2e5,m<=2e5個操作,區間加,問一個區間裏K的倍數。

這題空間???當成512MB吧。。n*sqrt(n)開得下

每個塊記cnt(x,i)表示第x個塊有多少數%K=i,以及整塊+標記add(x),然後回答詢問時默認一個塊裏的數都加上了add(x)即可,修改常規。

技術分享圖片
 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<string.h>
 4 #include<stdlib.h>
 5
#include<math.h> 6 //#include<iostream> 7 using namespace std; 8 9 int n,m,q,K; 10 #define maxn 200011 11 #define maxm 461 12 int cnt[maxm][maxn],a[maxn],bel[maxn],tot,add[maxm]; 13 void modify(int x,int y,int v) 14 { 15 if (bel[x]==bel[y]) 16 for (int i=x;i<=y;i++) cnt[bel[i]][a[i]]--,a[i]+=v,a[i]%=K,cnt[bel[i]][a[i]]++;
17 else 18 { 19 for (int i=bel[x]+1;i<bel[y];i++) add[i]+=v,add[i]%=K; 20 for (int i=x;bel[i]==bel[x];i++) cnt[bel[i]][a[i]]--,a[i]+=v,a[i]%=K,cnt[bel[i]][a[i]]++; 21 for (int i=y;bel[i]==bel[y];i--) cnt[bel[i]][a[i]]--,a[i]+=v,a[i]%=K,cnt[bel[i]][a[i]]++; 22 }
23 } 24 int query(int x,int y) 25 { 26 int ans=0; 27 if (bel[x]==bel[y]) 28 for (int i=x;i<=y;i++) ans+=(a[i]+add[bel[i]]==0 || a[i]+add[bel[i]]==K); 29 else 30 { 31 for (int i=bel[x]+1;i<bel[y];i++) ans+=cnt[i][add[i]?K-add[i]:0]; 32 for (int i=x;bel[x]==bel[i];i++) ans+=(a[i]+add[bel[i]]==0 || a[i]+add[bel[i]]==K); 33 for (int i=y;bel[y]==bel[i];i--) ans+=(a[i]+add[bel[i]]==0 || a[i]+add[bel[i]]==K); 34 } 35 return ans; 36 } 37 38 bool isdigit(char c) {return c>=0 && c<=9;} 39 int qread() 40 { 41 char c;int s=0;while (!isdigit(c=getchar())); 42 do s=s*10+c-0; while (isdigit(c=getchar())); return s; 43 } 44 int main() 45 { 46 n=qread(),q=qread(),K=qread(); 47 m=(int)sqrt(n); 48 for (int i=1;i<=n;i++) bel[i]=(i-1)/m+1; 49 tot=bel[n]; 50 51 for (int i=1;i<=n;i++) 52 { 53 a[i]=qread()%K; 54 cnt[bel[i]][a[i]]++; 55 } 56 57 char c; 58 for (int i=1,x,y,z;i<=q;i++) 59 { 60 while (!((c=getchar())>=a && c<=z)); 61 if (c==a) 62 { 63 x=qread(),y=qread(),z=qread(); 64 modify(x,y,z); 65 } 66 else 67 { 68 x=qread(),y=qread(); 69 printf("%d\n",query(x,y)); 70 } 71 while (c>=a && c<=z) c=getchar(); 72 } 73 return 0; 74 }
View Code

分塊試水--CODEVS5037 線段樹練習4加強版