码迷,mamicode.com
首页 > 其他好文 > 详细

loj6278 数列分块入门题2

时间:2018-02-10 23:25:58      阅读:423      评论:0      收藏:0      [点我收藏+]

标签:space   include   分块   排名   add   sort   c++   print   init   

题意:支持区间加,询问区间中元素排名

维护两个域。一个域维护原序列,一个域维护快内排序序列。

每次修改后更新快内排序序列。

修改时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

标签:space   include   分块   排名   add   sort   c++   print   init   

原文地址:https://www.cnblogs.com/mollnn/p/8439927.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!