有n个数,刚开始都为0
http://www.cnblogs.com/wuyiqi/archive/2012/05/27/2520642.html
add i , j 给i,j区间内的数都加1
Q i j 询问i、j间能被三整除的数的个数 http://lightoj.com/volume_showproblem.php?problem=1135
线段树记录三个域
对三取余为0的数的个数
。。。。。1.。。。。。
。。。。。2.。。。。。
可以保存在一个数组里面
考虑到每次给一个区间加1的时候,区间内对3取余为1的数的个数变成了对三取余为2,2的变成了0,0的变成了1
add i , j 给i,j区间内的数都加1
Q i j 询问i、j间能被三整除的数的个数 http://lightoj.com/volume_showproblem.php?problem=1135
线段树记录三个域
对三取余为0的数的个数
。。。。。1.。。。。。
。。。。。2.。。。。。
可以保存在一个数组里面
考虑到每次给一个区间加1的时候,区间内对3取余为1的数的个数变成了对三取余为2,2的变成了0,0的变成了1
所以每次更新到区间或者把信息(懒惰标记)往下传的时候只需要把相应的域做一下调整即可
做题过程:(在程序里面有写)
我发觉数组真的是和我过不去额。又开小了。10^5我以为5个1就行了呢。。。
然后就是我常犯的毛病:不看题(人家是从0-n-1),还有就是初始化(lazy没有初始化)。
这些都是后来的事情了。刚开始我图方便,将build直接写成memset了。然后一看结果输出的都是0,我就煞那间醒悟了,但是把lazy给漏掉了。。。
还有一点是中间需要一个ans数组作为中间变量,不然的话,原来的值就被覆盖了。
最后优化的一点是将那个1转成2等等的东西写成一个函数。
//started at 22:18
//submit at 22:47 RE
//change the size of shuzu ,submit at 22:49 WA
//change the start point and end point , submit at 22:51 WA
//change lazy[](initualize) ,submit ant 22 : 55, AC
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define lson l, m , rt << 1
#define rson m + 1, r, rt << 1 | 1
#define ls rt << 1
#define rs rt << 1 | 1
#define maxn 111111//RE了一次
#define havem int m = (l + r) >> 1
int hehe[3][maxn << 2],ans[3],lazy[maxn << 2];
void push_up(int rt){
for(int i = 0; i < 3; i ++){
hehe[i][rt] = hehe[i][ls] + hehe[i][rs];
}
}
void build(int l,int r,int rt){
lazy[rt] = 0;//这里wa了一次
if(l == r){
hehe[0][rt] = 1;
hehe[1][rt] = hehe[2][rt] = 0;
return ;
}havem;
build(lson); build(rson);
push_up(rt);
}
int t,n,Q,op,a,b;
void make(int add, int rt){//这里优化了一下
for(int i = 0; i < 3; i ++){
ans[(i + add) % 3] = hehe[i][rt];
}
for(int i = 0; i < 3; i ++){
hehe[i][rt] = ans[i];
}
}
void push_dn(int rt){
if(lazy[rt]){
int tmp = lazy[rt];
lazy[ls] += tmp;
lazy[rs] += tmp;
make(tmp,ls);
make(tmp,rs);
lazy[rt] = 0;
}
}
void update(int L, int R,int l,int r, int rt){
if(L <= l && r <= R){
lazy[rt] += 1;
//question : how do you increase the number
make(1,rt);
return;
}havem;
push_dn(rt);
if(L <= m) update(L,R,lson);
if(R > m) update(L,R,rson);
push_up(rt);
}
int query(int L,int R,int l,int r,int rt){
if(L <= l && r <= R) return hehe[0][rt];
int ret = 0;
havem; push_dn(rt);
if(L <= m) ret = query(L,R,lson);
if(R > m) ret += query(L,R,rson);
return ret;
}
int main(){
scanf("%d",&t);
for(int ca = 1; ca <= t; ca ++){
scanf("%d%d",&n,&Q);
build(0,n - 1,1);//从0-n-1,wa了一次
memset(ans,0,sizeof(ans));
printf("Case %d:\n",ca);
for(int i = 1; i <= Q; i ++){
scanf("%d",&op);
scanf("%d%d",&a,&b);
if(op == 0){
update(a,b,0,n - 1,1);
}else
printf("%d\n",query(a,b,0,n - 1,1));
}
}
return 0;
}