教主的魔法--分块

https://www.luogu.org/problemnew/show/P2801

第一次写分块的题,学习了这个视频:

https://www.bilibili.com/video/av6445624?from=search&seid=16889343910066931739

 1 void build()
 2 {
 3      block=sqrt(n);
 4      num=n/block;
 5      if(n%block) num++;
 6      for(int i=1;i<=num;i++)
 7      {
 8          l[i]=(i-1)*block+1;
 9          r[i]=block*i;
10      }
11      r[num]=n;
12      for(int i=1;i<=n;i++)
13        belong[i]=(i-1)/block+1;
14 }
build的模板
  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<math.h>
  4 #include<iostream>
  5 #include<stdlib.h>
  6 #include<algorithm>
  7 #include<queue>
  8 #include<vector>
  9 #include<string>
 10 #include<set>
 11 #include<cctype>
 12 #include<sstream>
 13 #define mem(a) memset(a,0,sizeof(a))
 14 #define LL long long
 15 const int N=1e9+5;
 16 const int M=1e6+10;
 17 using namespace std;
 18 int n,q,a[M],l[M],r[M],block,belong[M],num,add[M],b[M];
 19 int c;
 20 void reset(int n) //内排序
 21 {
 22    int x=l[belong[n]],y=r[belong[n]];
 23    for(int i=x;i<=y;i++)
 24     b[i]=a[i];
 25    sort(b+x,b+y+1);
 26 }
 27 int fin(int n,int c)
 28 {
 29     int x=l[n],y=r[n];
 30     int last=y;
 31     while(x<=y)
 32     {
 33         int m=(x+y)>>1;
 34         if(b[m]<c) x=m+1;
 35         else y=m-1;
 36     }
 37     return last-x+1;
 38 }
 39 void build()
 40 {
 41      block=sqrt(n);
 42      num=n/block;
 43      if(n%block) num++;
 44      for(int i=1;i<=num;i++)
 45      {
 46          l[i]=(i-1)*block+1;
 47          r[i]=block*i;
 48      }
 49      r[num]=n;
 50      for(int i=1;i<=n;i++)
 51        belong[i]=(i-1)/block+1,b[i]=a[i];
 52      for(int i=1;i<=num;i++)
 53         sort(b+l[i],b+r[i]+1);
 54      return;//
 55 }
 56 void update(int L,int R,int c)
 57 {
 58     if(belong[L]==belong[R])
 59     {
 60        for(int i=L;i<=R;i++)
 61        {
 62           a[i]+=c;
 63        }
 64       reset(L);//
 65        return;
 66     }
 67     for(int i=L;i<=r[belong[L]];i++)
 68         a[i]+=c;
 69     for(int i=l[belong[R]];i<=R;i++)
 70         a[i]+=c;
 71     reset(L);reset(R);
 72     for(int i=belong[L]+1;i<belong[R];i++)
 73     {
 74        add[i]+=c;
 75     }
 76 }
 77 int ask(int ll,int rr,int c)
 78 {
 79     int ans=0;
 80     if(belong[ll]==belong[rr])
 81     {
 82         for(int i=ll;i<=rr;i++)
 83         {
 84             if(a[i]+add[belong[i]]>=c) ans++;
 85         }
 86     }
 87     else
 88     {
 89         for(int i=ll;i<=r[belong[ll]];i++)
 90           if(a[i]+add[belong[i]]>=c)ans++;
 91         for(int i=l[belong[rr]];i<=rr;i++)
 92           if(a[i]+add[belong[i]]>=c) ans++;
 93     }
 94     for(int i=belong[ll]+1;i<belong[rr];i++)
 95     {
 96         ans+=fin(i,c-add[i]);
 97     }
 98     return ans;
 99 }
100 int main()
101 {
102   int L,R,c;
103   char s[5];
104   scanf("%d %d",&n,&q);
105   for(int i=1;i<=n;i++)
106   {
107      scanf("%d",&a[i]);
108   }
109   build();
110   while(q--)
111   {
112       scanf("%s %d%d%d",s,&L,&R,&c);
113       if(s[0]=='M')
114       {
115          update(L,R,c);
116       }
117       else
118       {
119          printf("%d\n",ask(L,R,c));
120       }
121   }
122 
123   return 0;
124 }
View Code

 

posted @ 2019-01-24 18:24  XXrl  阅读(134)  评论(0编辑  收藏  举报