Description
There are N numbers a[0],a[1]..a[N - 1]. Initally all are 0. You have to perform two types of operations :
1) Increase the numbers between indices A and B (inclusive) by 1. This is represented by the command "0 A B"
2) Answer how many numbers between indices A and B (inclusive) are divisible by 3. This is represented by the command "1 A B".
Input :
The first line contains two integers, N and Q. Each of the next Q lines are either of the form "0 A B" or "1 A B" as mentioned above.
Output :
Output 1 line for each of the queries of the form "1 A B" containing the required answer for the corresponding query.
Sample Input :
4 7
1 0 3
0 1 2
0 1 3
1 0 0
0 0 3
1 3 3
1 0 3
Sample Output :
4
1
0
2
Constraints :
1 <= N <= 100000
1 <= Q <= 100000
0 <= A <= B <= N - 1
#include <cstdio>
const int maxn = 100010;
int sum[maxn<<2][3],add[maxn<<2];
void pushup(int cur){
int ls = cur<<1,rs = cur<<1|1;
sum[cur][0] = sum[ls][0]+sum[rs][0];
sum[cur][1] = sum[ls][1]+sum[rs][1];
sum[cur][2] = sum[ls][2]+sum[rs][2];
}
void pushdown(int cur){
int ls = cur<<1,rs = cur<<1|1,tmp;
if(add[cur] != 0){
add[ls] = (add[ls]+add[cur])%3;
add[rs] = (add[rs]+add[cur])%3;
if(add[cur] == 1){
tmp = sum[ls][2];
sum[ls][2] = sum[ls][1];
sum[ls][1] = sum[ls][0];
sum[ls][0] = tmp;
}else if(add[cur] == 2){
tmp = sum[ls][0];
sum[ls][0] = sum[ls][1];
sum[ls][1] = sum[ls][2];
sum[ls][2] = tmp;
}
if(add[cur] == 1){
tmp = sum[rs][2];
sum[rs][2] = sum[rs][1];
sum[rs][1] = sum[rs][0];
sum[rs][0] = tmp;
}else if(add[cur] == 2){
tmp = sum[rs][0];
sum[rs][0] = sum[rs][1];
sum[rs][1] = sum[rs][2];
sum[rs][2] = tmp;
}
add[cur] = 0;
}
}
void bulid(int cur,int x,int y){
int mid = (x+y)>>1,ls = cur<<1,rs = cur<<1|1;
if(x == y){
sum[cur][0] = 1;
return;
}
bulid(ls,x,mid);
bulid(rs,mid+1,y);
pushup(cur);
}
void update(int cur,int x,int y,int s,int t){
int mid = (x+y)>>1,ls = cur<<1,rs = cur<<1|1;
if(x >= s && y <= t){
int tmp = sum[cur][2];
sum[cur][2] = sum[cur][1];
sum[cur][1] = sum[cur][0];
sum[cur][0] = tmp;
add[cur] = (add[cur]+1)%3;
return;
}
pushdown(cur);
if(mid >= s) update(ls,x,mid,s,t);
if(mid+1 <= t) update(rs,mid+1,y,s,t);
pushup(cur);
}
void query(int cur,int x,int y,int s,int t,int &ans){
int mid = (x+y)>>1,ls = cur<<1,rs = cur<<1|1;
if(x >= s && y <= t){
ans += sum[cur][0];
return;
}
pushdown(cur);
if(mid >= s) query(ls,x,mid,s,t,ans);
if(mid+1 <= t) query(rs,mid+1,y,s,t,ans);
}
int main(){
int n,q,op,a,b;
scanf("%d%d",&n,&q);
bulid(1,0,n-1);
while(q--){
scanf("%d%d%d",&op,&a,&b);
if(op == 0) update(1,0,n-1,a,b);
else{
int ans = 0;
query(1,0,n-1,a,b,ans);
printf("%d\n",ans);
}
}
return 0;
}