NYOJ 1068 ST(线段树之 成段更新+区间求和)
来源:互联网 发布:stm8 c语言编程 编辑:程序博客网 时间:2024/04/19 07:35
ST
时间限制:1000 ms | 内存限制:65535 KB
难度:1
- 描述
“麻雀”lengdan用随机数生成了后台数据,但是笨笨的他被妹纸的问题给难住了。。。
已知lengdan生成了N(1=<N<=10005)个随机整数,妹子对这些数可能有以下几种操作或询问:
1,A a b c 表示给区间a到b内每个数都加上c;
2,S a b 表示输出区间a到b内的和;
3,Q a b 表示区间a到b内的奇数的个数;
为了使妹纸不口渴,所以我们决定妹纸的询问次数少一点,即(1=<M<=10000,M为询问次数)。
- 输入
- 多组测试数据。
每组测试数据第一行包含两个数N,M,表示N个整数,执行M次询问或操作。
紧接着一行输入N个整数,输入数据保证在int范围内。
接下来M行,每行输入一种操作。 - 输出
- 每次对于操作2和3,输出结果。
- 样例输入
5 51 2 3 4 5Q 1 4S 1 5A 1 4 1S 1 5Q 2 5
- 样例输出
215193
- 简单的线段树成段更新+区间求和,只是附加了求区间内的奇数个数。由于之前没有写过线段树成段更新的题目,导致因为一条向下更新的语句忘记写,调了一个上午才发现错误。
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const int N = 10010;#define lson l, mid, root<<1#define rson mid+1, r, root<<1|1struct node{ int l, r; LL sum, odd, add;}a[N<<2];void PushUp(int root){ a[root].sum = a[root<<1].sum + a[root<<1|1].sum; a[root].odd = a[root<<1].odd + a[root<<1|1].odd;}void PushDown(int len, int root){ if(a[root].add) { a[root<<1].add += a[root].add; a[root<<1|1].add += a[root].add; a[root<<1].sum += LL(len - (len>>1)) * a[root].add; a[root<<1|1].sum += LL(len>>1) * a[root].add; if(a[root].add % 2 == 1) { a[root<<1].odd = len - (len>>1) - a[root<<1].odd; a[root<<1|1].odd = (len>>1) - a[root<<1|1].odd; } a[root].add = 0; }}void build_tree(int l, int r, int root){ a[root].l = l; a[root].r = r; a[root].add = 0; a[root].odd = 0; if(l == r) { scanf("%lld",&a[root].sum); if(a[root].sum % 2 == 1) a[root].odd = 1; return; } int mid = (l + r) >> 1; build_tree(lson); build_tree(rson); PushUp(root);}void update(int l, int r, int root, LL k){ if(l <= a[root].l && r >= a[root].r) { a[root].add += k; a[root].sum += LL(a[root].r - a[root].l + 1) * k; if(k % 2 == 1) a[root].odd = (a[root].r - a[root].l + 1) - a[root].odd; return; } PushDown(a[root].r - a[root].l + 1, root); int mid = (a[root].l + a[root].r) >> 1; if(l <= mid) update(l, r, root<<1, k); if(r > mid) update(l, r, root<<1|1, k); PushUp(root);}LL Query(int l, int r, int root, char ch){ if(l <= a[root].l && r >= a[root].r) { if(ch == 'Q') return a[root].odd; else if(ch == 'S') return a[root].sum; } PushDown(a[root].r - a[root].l + 1, root); LL ans = 0; int mid = (a[root].l + a[root].r) >> 1; if(l <= mid) ans += Query(l, r, root<<1, ch); if(r > mid) ans += Query(l, r, root<<1|1, ch); return ans;}int main(){ int n, m, i, x, y; LL z; char ch[5]; while(~scanf("%d%d",&n,&m)) { build_tree(1, n, 1); while(m--) { scanf("%s",ch); if(ch[0] == 'A') { scanf("%d%d%lld",&x,&y,&z); update(x, y, 1, z); } else { scanf("%d%d",&x,&y); printf("%lld\n", Query(x, y, 1, ch[0])); } } } return 0;}
0 0
- NYOJ 1068 ST(线段树之 成段更新+区间求和)
- 线段树,成段更新,区间求和
- 线段树(成段更新,区间求和lazy操作 )
- 线段树POJ3468(成段更新,区间求和)
- 线段树POJ3468(成段更新,区间求和)
- POJ 3468-A Simple Problem with Integers(线段树:成段更新,区间求和)
- POJ3468 A Simple Problem with Integers 线段树 区间成段更新+区间求和
- poj 3468 线段树(成段增减 区间求和)
- NYOJ-士兵杀敌(五) 线段树区间更新、线段求和
- nyoj 1068 ST【线段树】求和&&奇数个数
- 线段树(区间更新求和)
- 线段树(单点更新,区间求和)
- 线段树 (区间更新求和)
- 线段树 区间更新(成段更新) HDU1698
- Count the Colors(线段树之区间成段更新)
- poj 3468 A Simple Problem with Integers(线段树)(第二部分 成段更新,区间求和)
- hdu 1698 Just a Hook(线段树 成段更新+总区间求和)
- hdu 1698 Just a hook 线段树 成段更新~~区间求和
- hdu4501-注意小细节(我的惯性写法)
- c 语言 结构体
- 如何成为一名黑客(How To Become A Hacker)
- android中handler用法总结
- android 消息机制
- NYOJ 1068 ST(线段树之 成段更新+区间求和)
- 动态树 Link-Cut Trees
- 机房收费系统之窗体遍历的实现
- AC自动机
- 有铅焊锡丝与无铅焊锡丝的性能差异大解析
- 二分查找的C语言实现
- spring中的设计模式-模版方法
- servlet实现文件上传
- easyui combotree 加载本地数据