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

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

时间:2017-12-12 15:17:40      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:hid   bsp   gif   add   lap   namespace   view   练习   code   

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

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\n",query(x,y));
70         }
71         while (c>=a && c<=z) c=getchar();
72     }
73     return 0;
74 }
View Code

 

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

标签:hid   bsp   gif   add   lap   namespace   view   练习   code   

原文地址:http://www.cnblogs.com/Blue233333/p/8027466.html

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