• 教主的魔法--分块


    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
    ",ask(L,R,c));
    120       }
    121   }
    122 
    123   return 0;
    124 }
    View Code
  • 相关阅读:
    IO流上机作业
    数据结构堆排序
    数据结构实训报告
    字符串的基本操作
    java窗口的简单切换
    判断一个串B位于串A的位置
    c语言实现数组转置,加减,乘法运算
    java异常处理
    弹奏乐器
    课程总结
  • 原文地址:https://www.cnblogs.com/XXrll/p/10316146.html
Copyright © 2020-2023  润新知