1. 程式人生 > >loj6278 數列分塊入門題2

loj6278 數列分塊入門題2

lower block color sort ace pan 入門 else lock

題意:支持區間加,詢問區間中元素排名

維護兩個域。一個域維護原序列,一個域維護快內排序序列。

每次修改後更新快內排序序列。

修改時O(sqrt(n)log(sqrt(n)))

詢問時O(sqrt(n)log(sqrt(n)))

大概是這個量級吧

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int bl[100005],bla,a[100005],a0[100005],b[100005],bi[100005],n;
 5 int t1,t2,t3,t4;
 6 
 7 void init() {
 8     bla=sqrt(n);
 9     for
(int i=1;i<=n;i++) 10 bl[i]=(i-1)/bla+1, 11 bi[i]=(i-1)%bla+1; 12 for (int l=1;l<=n;l+=bla) { 13 for(int i=bl[l]*bla-bla+1;i<=bl[l]*bla;i++) 14 a[i]=a0[i]; 15 sort(a+bl[l]*bla-bla+1,a+bl[l]*bla+1); 16 } 17 } 18 19 void add(int l,int r,int c){
20 if(bl[l]==bl[r]) { 21 for(int i=l;i<=r;i++) 22 a0[i]+=c; 23 for(int i=bl[l]*bla-bla+1;i<=bl[l]*bla;i++) 24 a[i]=a0[i]; 25 sort(a+bl[l]*bla-bla+1,a+bl[l]*bla+1); 26 } 27 else { 28 for(int i=l;i<=bl[l]*bla;i++) 29 a0[i]+=c;
30 for(int i=bl[l]*bla-bla+1;i<=bl[l]*bla;i++) 31 a[i]=a0[i]; 32 sort(a+bl[l]*bla-bla+1,a+bl[l]*bla+1); 33 for(int i=bl[r]*bla-bla+1;i<=r;i++) 34 a0[i]+=c; 35 for(int i=bl[r]*bla-bla+1;i<=bl[r]*bla;i++) 36 a[i]=a0[i]; 37 sort(a+bl[r]*bla-bla+1,a+bl[r]*bla+1); 38 for(int i=bl[l]+1;i<bl[r];i++) 39 b[i]+=c; 40 } 41 } 42 43 int query(int l,int r,long long c){ 44 int ans=0; 45 if(bl[l]==bl[r]) { 46 for(int i=l;i<=r;i++) 47 ans+=(a0[i]<c-b[bl[l]]); 48 } 49 else { 50 for(int i=l;i<=bl[l]*bla;i++) 51 ans+=(a0[i]<c-b[bl[l]]); 52 for(int i=bl[r]*bla-bla+1;i<=r;i++) 53 ans+=(a0[i]<c-b[bl[r]]); 54 for(int i=bl[l]+1;i<bl[r];i++) 55 ans+=lower_bound(a+i*bla-bla+1,a+i*bla+1,c-b[i])-(a+i*bla-bla+1); 56 } 57 return ans; 58 } 59 60 void printblock(){ 61 /*for(int i=1;i<=n/bla+(n%bla)?1:0;i++) { 62 printf("block %d : %d\n",i,b[i]); 63 printf(" a0: "); 64 for(int j=1;j<=bla;j++) printf("%d ",a0[i*bla-bla+j]); 65 printf("\n"); 66 printf(" a: "); 67 for(int j=1;j<=bla;j++) printf("%d ",a[i*bla-bla+j]); 68 printf("\n"); 69 }*/ 70 } 71 72 int main(){ 73 ios::sync_with_stdio(false); 74 cin>>n; 75 for(int i=1;i<=n;i++) 76 cin>>a0[i]; 77 init(); 78 printblock(); 79 for(int i=1;i<=n;i++) { 80 cin>>t1>>t2>>t3>>t4; 81 if(t1==0){ 82 add(t2,t3,t4); 83 } 84 else { 85 printf("%d\n",query(t2,t3,t4*t4)); 86 } 87 printblock(); 88 } 89 }

loj6278 數列分塊入門題2