• 分块试水--CODEVS5037 线段树练习4加强版


    感觉这才算入门题吧。。前面那些线段树练习,改几个字符就过了一定要搞成几道题。。

    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
    ",query(x,y));
    70         }
    71         while (c>='a' && c<='z') c=getchar();
    72     }
    73     return 0;
    74 }
    View Code
  • 相关阅读:
    my functions.h
    MFC中GDI之CBitmap(位图)
    MFC中GDI之CFont(字体)
    MFC中GDI之CBrush(画刷)
    MFC中SDI设置状态栏显示时间
    MFC中自定义消息
    MFC常用控件类
    MFC中改变窗口大小MoveWindow...
    MFC中建立关联变量的几种方式
    软件默认端口整理
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8027466.html
Copyright © 2020-2023  润新知