lightoj 1135 - Count the Multiples of 3

一个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 ij 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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值