1135 - Count the Multiples of 3

  PDF (English) Statistics Forum
Time Limit: 3 second(s) Memory Limit: 64 MB

You have an array with n elements which is indexed from 0 to n - 1. Initially all elements are zero. Now you have to deal with two types of operations

  1. Increase the numbers between indices i and j (inclusive) by 1. This is represented by the command ‘0 i j‘.
  2. Answer how many numbers between indices i and j (inclusive) are divisible by 3. This is represented by the command ‘1 i j‘.

Input

Input starts with an integer T (≤ 5), denoting the number of test cases.

Each case starts with a line containing two integers n (1 ≤ n ≤ 105) and q (1 ≤ q ≤ 50000) denoting the number of queries. Each query will be either in the form ‘0 i j‘ or ‘1 i j‘ where i, j are integers and 0 ≤ i ≤ j < n.

Output

For each case, print the case number first. Then for each query in the form ‘1 i j‘, print the desired result.

Sample Input

Output for Sample Input


1

10 9

0 0 9

0 3 7

0 1 4

1 1 7

0 2 2

1 2 4

1 8 8

0 5 8

1 6 9


Case 1:

2

3

0

2

Note

Dataset is huge, use faster i/o methods.



Special Thanks: Jane Alam Jan (Description, Solution, Dataset)

思路:线段树+lazy标记区间更新

线段数维护的是mod3为0,1,2的个数,然后lazy标记区间更新就可以了,复杂度(n*log(n)^2);

  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<string.h>
  5 #include<stdlib.h>
  6 #include<queue>
  7 #include<math.h>
  8 #include<vector>
  9 using namespace std;
 10 typedef struct node
 11 {
 12         int mod1;
 13         int mod2;
 14         int mod3;
 15         int val;
 16         node()
 17         {
 18                 val = 0;
 19         }
 20 } tr;
 21 tr tree[4*200005];
 22 void build(int l,int r,int k);
 23 void mov(int k);
 24 void in(int l,int r,int k,int nn,int mm);
 25 void up(int k);
 26 int query(int l,int r,int k,int nn,int mm);
 27 int main(void)
 28 {
 29         int i,j;
 30         int T;
 31         int __ca = 0;
 32         scanf("%d",&T);
 33         while(T--)
 34         {
 35                 int n,m;
 36                 scanf("%d %d",&n,&m);
 37                 memset(tree,0,sizeof(tree));
 38                 build(0,n-1,0);
 39                 printf("Case %d:\n",++__ca);
 40                 while(m--)
 41                 {
 42                         int val ,x,y;
 43                         scanf("%d%d%d",&val,&x,&y);
 44                         if(val)
 45                         {
 46                                 printf("%d\n",query(x,y,0,0,n-1));
 47                         }
 48                         else
 49                         {
 50                                 in(x,y,0,0,n-1);
 51                         }
 52                 }
 53         }
 54         return 0;
 55 }
 56 void build(int l,int r,int k)
 57 {
 58         if(l==r)
 59         {
 60                 tree[k].mod3 = 1;
 61                 tree[k].mod1 = 0;
 62                 tree[k].mod2 = 0;
 63                 tree[k].val = 0;
 64                 return ;
 65         }
 66         tree[k].val = 0;
 67         build(l,(l+r)/2,2*k+1);
 68         build((l+r)/2+1,r,2*k+2);
 69         tree[k].mod1 = tree[2*k+1].mod1 + tree[2*k+2].mod1;
 70         tree[k].mod2 = tree[2*k+1].mod2 + tree[2*k+2].mod2;
 71         tree[k].mod3 = tree[2*k+1].mod3 + tree[2*k+2].mod3;
 72 }
 73 void mov(int k)
 74 {
 75         int x = tree[k].mod1;
 76         tree[k].mod1 = tree[k].mod3;
 77         tree[k].mod3 = tree[k].mod2;
 78         tree[k].mod2 = x;
 79         return ;
 80 }
 81 void in(int l,int r,int k,int nn,int mm)
 82 {
 83         if(l > mm||r < nn)
 84         {
 85                 return ;
 86         }
 87         else if(l <= nn&& r>=mm)
 88         {
 89                 tree[k].val++;
 90                 tree[k].val%=3;
 91                 int x = tree[k].val;
 92                 tree[k].val = 0;
 93                 if(x)
 94                 {
 95                         tree[2*k+1].val += x;
 96                         tree[2*k+2].val +=x;
 97                         tree[2*k+1].val%=3;
 98                         tree[2*k+2].val%=3;
 99                         while(x)
100                         {
101                                 mov(k);
102                                 x--;
103                         }
104                 }
105                 up(k);
106         }
107         else
108         {
109                 int x= tree[k].val;
110                 tree[2*k+1].val = (tree[2*k+1].val + x)%3;
111                 tree[2*k+2].val = (tree[2*k+2].val + x)%3;
112                 tree[k].val = 0;
113                 in(l,r,2*k+1,nn,(nn+mm)/2);
114                 in(l,r,2*k+2,(nn+mm)/2+1,mm);
115         }
116 }
117 void up(int k)
118 {
119         if(k == 0)
120                 return ;
121         while(k)
122         {
123                 k = (k-1)/2;
124                 int xll = 2*k+1;
125                 int xrr = 2*k+2;
126                 if(tree[xll].val)
127                 {
128                         int x = tree[xll].val;
129                         {
130                                 tree[xll].val = 0;
131                                 tree[2*xll+1].val = (tree[2*xll+1].val + x)%3;
132                                 tree[2*xll+2].val = (tree[2*xll+2].val + x)%3;
133                                 while(x)
134                                 {
135                                         mov(xll);
136                                         x--;
137                                 }
138                         }
139                 }
140                 if(tree[xrr].val)
141                 {
142                         int x= tree[xrr].val;
143                         tree[2*xrr+1].val = (tree[2*xrr+1].val+x)%3;
144                         tree[2*xrr+2].val = (tree[2*xrr+2].val+x)%3;
145                         tree[xrr].val = 0;
146                         while(x)
147                         {
148                                 mov(xrr);
149                                 x--;
150                         }
151                 }
152                 tree[k].mod1 = tree[2*k+1].mod1+tree[2*k+2].mod1;
153                 tree[k].mod2 = tree[2*k+1].mod2+tree[2*k+2].mod2;
154                 tree[k].mod3 = tree[2*k+1].mod3+tree[2*k+2].mod3;
155         }
156 }
157 int query(int l,int r,int k,int nn,int mm)
158 {
159         if(l > mm||r < nn)
160         {
161                 return 0;
162         }
163         else if(l <=nn&&r>=mm)
164         {
165                 if(tree[k].val)
166                 {
167                         int x= tree[k].val;
168                         tree[k].val = 0;
169                         tree[2*k+1].val = (tree[2*k+1].val+x)%3;
170                         tree[2*k+2].val = (tree[2*k+2].val+x)%3;
171                         while(x)
172                         {
173                                 mov(k);
174                                 x--;
175                         }
176                 }
177                 up(k);
178                 return tree[k].mod3;
179         }
180         else
181         {
182                 if(tree[k].val)
183                 {
184                         int x = tree[k].val;
185                         tree[k].val = 0;
186                         tree[2*k+1].val = (tree[2*k+1].val+x)%3;
187                         tree[2*k+2].val = (tree[2*k+2].val+x)%3;
188                 }
189                 int nx = query(l,r,2*k+1,nn,(nn+mm)/2);
190                 int ny = query(l,r,2*k+2,(nn+mm)/2+1,mm);
191                 return nx+ny;
192         }
193 }
时间: 2025-01-01 11:20:41

1135 - Count the Multiples of 3的相关文章

LightOJ 1135 - Count the Multiples of 3 线段树

http://www.lightoj.com/volume_showproblem.php?problem=1135 题意:给定两个操作,一个对区间所有元素加1,一个询问区间能被3整除的数有多少个. 思路:要求被3整除,我们可以记录3个状态,当前区间模3余1的 余2的 余0的,那么对一个数增加的时候,直接交换不同余数下的个数就可以了. /** @Date : 2016-12-06-20.00 * @Author : Lweleth ([email protected]) * @Link : ht

nodejs api 中文文档

文档首页 英文版文档 本作品采用知识共享署名-非商业性使用 3.0 未本地化版本许可协议进行许可. Node.js v0.10.18 手册 & 文档 索引 | 在单一页面中浏览 | JSON格式 目录 关于本文档 稳定度 JSON 输出 概述 全局对象 global process console 类: Buffer require() require.resolve() require.cache require.extensions __filename __dirname module e

Java [Leetcode 204]Count Primes

题目描述: Description: Count the number of prime numbers less than a non-negative number, n. 解题思路: Let's start with a isPrime function. To determine if a number is prime, we need to check if it is not divisible by any number less than n. The runtime comp

【leetcode】204 - Count Primes

Description:Count the number of prime numbers less than a non-negative number, n. Hint: Let's start with a isPrime function. To determine if a number is prime, we need to check if it is not divisible by any number less than n. The runtime complexity

[LeetCode]54. Count Primes统计素数

Description: Count the number of prime numbers less than a non-negative number, n. Credits:Special thanks to @mithmatt for adding this problem and creating all test cases. 解法1:扫描一遍,依次判断每个数是否是素数,会超时Time Limit Exceeded class Solution { public: int coun

题目1135:字符串排序 Java/c++

题目描述: 先输入你要输入的字符串的个数.然后换行输入该组字符串.每个字符串以回车结束,每个字符串少于一百个字符. 如果在输入过程中输入的一个字符串为"stop",也结束输入. 然后将这输入的该组字符串按每个字符串的长度,由小到大排序,按排序结果输出字符串. 输入: 字符串的个数,以及该组字符串.每个字符串以'\n'结束.如果输入字符串为"stop",也结束输入. 输出: 可能有多组测试数据,对于每组数据, 将输入的所有字符串按长度由小到大排序输出(如果有"

c#数组的count()和length的区别

C# 数组中 Length 表示数组项的个数,是个属性. 而 Count() 也是表示项的个数,是个方法,它的值和 Length 一样.但实际上严格地说 Count() 不是数组的内容,而是 IEnumerable 的内容.这也是为什么 C# 2.0 时数组不能用 Count(),而 3.0 后就可以用 Count() 的原因. 对于数组,据说用 Length 快于 Count(). 所以一般情况:数组我用 Length,IEnumerable(比如 List)我用 Count().

[LeetCode]Count Primes

题目:Count Primes 统计1-n的素数的个数. 思路1: 通常的思想就是遍历(0,n)范围内的所有数,对每个数i再遍历(0,sqrt(i)),每个除一遍来判断是否为素数,这样时间复杂度为O(n*sqrt(n)). 具体实现不在贴代码,过程很简单,两重循环就可以解决.但是效率很差,n较大时甚至会花几分钟才能跑完. 思路2: 用埃拉特斯特尼筛法的方法来求素数,时间复杂度可以达到O(nloglogn). 首先开一个大小为n的数组prime[],从2开始循环,找到一个质数后开始筛选出所有非素数

LeetCode OJ:Count Primes(质数计数)

Count the number of prime numbers less than a non-negative number, n. 计算小于n的质数的个数,当然就要用到大名鼎鼎的筛法了,代码如下,写的有点乱不好意思. 1 class Solution { 2 public: 3 int countPrimes(int n) { 4 vector<int> vtor(n + 1, 0); 5 vector<int> ret; 6 for (int i = 0; i <=