nyoj 1068 ST【线段树】求和&&奇数个数
来源:互联网 发布:centos ibus 设置 编辑:程序博客网 时间:2024/05/01 21:55
ST
时间限制:1000 ms | 内存限制:65535 KB
难度:2
- 描述
“麻雀”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为询问次数)。
唉,你说妹纸一直进行操作1该多好啊,嘎嘎。。。
- 输入
- 多组测试数据。
每组测试数据第一行包含两个数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<stdio.h>#include<string.h>#include<algorithm>#define maxn 100005typedef long long ll;using namespace std;ll sum[maxn*4],num[maxn*4],add[maxn*4];void pushdown(int rt,int len){if(add[rt]){int tp=rt<<1,tm=len>>1;sum[tp]+=ll(len-tm)*add[rt];sum[tp|1]+=(ll)tm*add[rt];add[tp]+=add[rt];add[tp|1]+=add[rt];if(add[rt]&1)//奇偶翻转 {num[tp]=len-tm-num[tp];num[tp|1]=tm-num[tp|1];}add[rt]=0;}}void build(int rt,int l,int r){sum[rt]=num[rt]=add[rt]=0;if(l==r){scanf("%lld",&sum[rt]);if(sum[rt]&1){num[rt]=1;}return;}int mid=(l+r)>>1,tp=rt<<1;build(tp,l,mid);build(tp|1,mid+1,r);sum[rt]=sum[tp]+sum[tp|1];num[rt]=num[tp]+num[tp|1];}void update(int rt,int l,int r,int a,int b,int c){if(l>=a&&r<=b){sum[rt]+=ll(r-l+1)*c;add[rt]+=(ll)c; if(c&1){num[rt]=r-l+1-num[rt];//所加值是奇数的话,奇偶的个数翻转 }return;}pushdown(rt,r-l+1);int mid=(l+r)>>1,tp=rt<<1;if(mid>=a){update(tp,l,mid,a,b,c);}if(mid<b){update(tp|1,mid+1,r,a,b,c);}sum[rt]=sum[tp]+sum[tp|1];num[rt]=num[tp]+num[tp|1];}ll find(int rt,int l,int r,int a,int b,char p){if(l>=a&&r<=b){if(p=='S'){return sum[rt];}return num[rt];}pushdown(rt,r-l+1);int mid=(l+r)>>1,tp=rt<<1;ll res=0;if(mid>=a){res+=find(tp,l,mid,a,b,p);}if(mid<b){res+=find(tp|1,mid+1,r,a,b,p);}return res;}int main(){int n,m;//freopen("shuju.txt","r",stdin);while(~scanf("%d%d",&n,&m)){build(1,1,n);for(int i=0;i<m;++i){char s[5];int a,b,c;scanf("%s%d%d",s,&a,&b);if(s[0]=='A'){scanf("%d",&c);update(1,1,n,a,b,c);continue;}printf("%lld\n",find(1,1,n,a,b,s[0]));}}return 0;}
0 0
- nyoj 1068 ST【线段树】求和&&奇数个数
- NYOJ 1068 ST(线段树之 成段更新+区间求和)
- NYOJ 1068 ST(线段树插线问线)
- NYOJ-奇数个数
- nyoj-557-奇数个数
- nyoj 116 士兵杀敌(二)【线段树】区间求和
- NYOJ士兵杀敌(一) 线段树区间求和
- nyoj1068 ST 线段树
- NYOJ-士兵杀敌(五) 线段树区间更新、线段求和
- 奇数求和
- 奇数求和
- RMQ问题 (st+线段树)
- POJ 3264 线段树 ST
- hdu1394~线段树求和
- 线段树区间求和
- 线段树求和,最大公约数
- 【BJTU+求和+线段树】
- 线段树求和
- HDU 3966 Aragorn's Story(树链剖分+线段树)
- Python:为什么会选择Python语言
- 判断字符串中是否包含emoji表情
- 从零开始学Swift计时器App开发
- 总结使人进步,可视化界面GUI应用开发总结:Android、iOS、Web、Swing、Windows开发等
- nyoj 1068 ST【线段树】求和&&奇数个数
- linux安装nginx并设置https(openssl)
- 编解码JSON数据
- 关于提高MYSQL性能的几个经验
- C++与汇编
- composer安装yii2
- LeetCode-Add Two Numbers
- HDU 1754 I Hate It(线段树)
- cf #311 E. Ann and Half-Palindrome (dp+字典树)