首页 > 代码库 > LightOJ 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 (SoungEarlf@gmail.com) * @Link : https://github.com/ * @Version : */#include<bits/stdc++.h>#define LL long long#define PII pair#define MP(x, y) make_pair((x),(y))#define fi first#define se second#define PB(x) push_back((x))#define MMG(x) memset((x), -1,sizeof(x))#define MMF(x) memset((x),0,sizeof(x))#define MMI(x) memset((x), INF, sizeof(x))using namespace std;const int INF = 0x3f3f3f3f;const int N = 1e5+20;const double eps = 1e-8;struct yuu{ int l, r; int add; int m0, m1, m2;}tt[N << 2];void pushup(int p){ tt[p].m0 = tt[p << 1].m0 + tt[p << 1 | 1].m0; tt[p].m1 = tt[p << 1].m1 + tt[p << 1 | 1].m1; tt[p].m2 = tt[p << 1].m2 + tt[p << 1 | 1].m2;}void pushdown(int p){ if(tt[p].add != 0) { tt[p].add %= 3; /// tt[p << 1].add += tt[p].add; if(tt[p].add == 2) { swap(tt[p << 1].m0 , tt[p << 1].m1); swap(tt[p << 1].m0 , tt[p << 1].m2); } else if(tt[p].add == 1) { swap(tt[p << 1].m0 , tt[p << 1].m2); swap(tt[p << 1].m1 , tt[p << 1].m0); } /// tt[p << 1 | 1].add += tt[p].add; if(tt[p].add == 2) { swap(tt[p << 1 | 1].m0 , tt[p << 1 | 1].m1); swap(tt[p << 1 | 1].m0 , tt[p << 1 | 1].m2); } else if(tt[p].add == 1) { swap(tt[p << 1 | 1].m0 , tt[p << 1 | 1].m2); swap(tt[p << 1 | 1].m1 , tt[p << 1 | 1].m0); } tt[p].add = 0; }}void build(int l, int r, int p){ tt[p].l = l; tt[p].r = r; tt[p].add = tt[p].m0 = tt[p].m2 = tt[p].m1 = 0; if(l == r) { tt[p].m0 = 1; return ; } int mid = (l + r) >> 1; build(l , mid, p << 1); build(mid + 1, r, p << 1 | 1); pushup(p);}void updata(int l, int r, int v, int p){ if(l <= tt[p].l && r >= tt[p].r) { tt[p].add += v; swap(tt[p].m0 , tt[p].m2); swap(tt[p].m1 , tt[p].m0); return ; } pushdown(p); int mid = (tt[p].l + tt[p].r) >> 1; if(l <= mid) updata(l, r, v, p << 1); if(r > mid) updata(l, r, v, p << 1 | 1); pushup(p);}int query(int l, int r, int p){ if(l <= tt[p].l && r >= tt[p].r) { return tt[p].m0; } pushdown(p); int mid = (tt[p].l + tt[p].r) >> 1; int ans = 0; if(l <= mid) ans += query(l, r, p << 1); if(r > mid) ans += query(l, r, p << 1 | 1); return ans;}int main(){ int T; int cnt = 0; cin >> T; while(T--) { int n, q; scanf("%d%d", &n, &q); build(1, n, 1); printf("Case %d:\n", ++cnt); while(q--) { int t, x, y; scanf("%d%d%d", &t ,&x ,&y); if(t) printf("%d\n", query(x+1, y+1, 1)); else updata(x+1, y+1, 1, 1); } } return 0;}
LightOJ 1135 - Count the Multiples of 3 线段树
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。