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
原创粉丝点击