一个lazy标记的很不错的学习的题。。。
题意是说,有0---n-1个数,初始化都为0。有两种操作:
0 i j, 闭区间[ i , j ]上的每个数都加1
1 i j,询问闭区间[ i , j ] 中,是3的倍数有多少个。
题目如下:
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 |
错了好多次。。。首先lazy标记不会写了,然后,开数组时。。一没注意开反了。。。MLE了好几次。。。改了过后。。。由于我cin和scanf这些混用。。。re了。。。虽然我关掉了ios和stdio之间的同步。。。Orz 最后还rp有问题...别人交的时候,oj好的。。。我一交就judge error了。。。。各种无语。。。不过最后还是过了~
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define LL __int64
#define ls v<<1
#define rs v<<1|1
#define fp(x,i,n) for(int i=x;i<n;i++)
//#define LOCAL
using namespace std;
const int INF=0x3ffffff;
const int MAXN=111111;
int tree[3][MAXN<<2],lazy[MAXN<<2];
void push_up(int v){
tree[0][v]=tree[0][ls]+tree[0][rs];
tree[1][v]=tree[1][ls]+tree[1][rs];
tree[2][v]=tree[2][ls]+tree[2][rs];
}
void build(int l,int r,int v){
lazy[v]=0;
if(l==r){
tree[0][v]=1;
tree[1][v]=tree[2][v]=0;
return ;
}
int mid=(l+r)>>1;
build(l,mid,ls);
build(mid+1,r,rs);
push_up(v);
}
void make(int v){
int tmp=tree[2][v];
tree[2][v]=tree[1][v];
tree[1][v]=tree[0][v];
tree[0][v]=tmp;
}
void push_down(int v){
if(lazy[v])
{
lazy[ls]+=lazy[v];
lazy[rs]+=lazy[v];
int tmp=lazy[v]%3;
fp(0,i,tmp){
make(ls);
make(rs);
}
lazy[v]=0;
}
}
void update(int L,int R,int l,int r,int v){
if(L<=l && R>=r){
lazy[v]++;
make(v);
return ;
}
push_down(v);
int mid=(l+r)>>1;
if(L<=mid) update(L,R,l,mid,ls);
if(R>mid) update(L,R,mid+1,r,rs);
push_up(v);
}
int query(int L,int R,int l,int r,int v){
if(L<=l && R>=r){
return tree[0][v];
}
push_down(v);
int ans=0,mid=(l+r)>>1;
if(L<=mid) ans+=query(L,R,l,mid,ls);
if(R>mid) ans+=query(L,R,mid+1,r,rs);
return ans;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
//ios::sync_with_stdio(false);
int t,n,q,op,a,b;
scanf("%d",&t);
fp(1,ca,t+1){
scanf("%d%d",&n,&q);
printf("Case %d:\n",ca);
build(1,n,1);//往后挪动了一位原题是0--n-1
fp(0,i,q){
scanf("%d%d%d",&op,&a,&b);
if(op==0){
update(a+1,b+1,1,n,1);
}
else
printf("%d\n",query(a+1,b+1,1,n,1));
}
}
return 0;
}