线段树
来源:互联网 发布:店铺复制软件 编辑:程序博客网 时间:2024/06/05 11:10
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define LL long longLL x[10010],sum;struct Node{ LL l,r,sum,flag,odd,even;} node[100010];void build_tree(LL l,LL r,LL n)//建树{ node[n].flag=0,node[n].l=l,node[n].r=r; if(l==r) { node[n].sum=x[l]; if(x[l]&1ll) node[n].odd=1ll,node[n].even=0; else node[n].odd=0,node[n].even=1ll; return ; } LL mid=(l+r)>>1ll,L=n<<1ll,R=(n<<1ll)|1ll; build_tree(l,mid,L); build_tree(mid+1ll,r,R); node[n].sum=node[L].sum+node[R].sum; node[n].odd=node[L].odd+node[R].odd; node[n].even=node[L].even+node[R].even;}void pushdown(LL n)//下放{ if(node[n].flag!=0) { LL L=n<<1ll,R=(n<<1ll)|1ll; if(node[n].flag&1ll) { swap(node[L].odd,node[L].even); swap(node[R].odd,node[R].even); } node[L].flag+=node[n].flag,node[R].flag+=node[n].flag;//标记下放子节点 node[L].sum+=(node[L].r-node[L].l+1ll)*node[n].flag;//更新子节点的值 node[R].sum+=(node[R].r-node[R].l+1ll)*node[n].flag;//同上 node[n].flag=0;//清空标记 }}void update(LL l,LL r,LL add,LL n)//更新{ if(node[n].l==l&&node[n].r==r) { node[n].flag+=add; node[n].sum+=(node[n].r-node[n].l+1ll)*add;//更新当前节点值 if(add&1ll) swap(node[n].odd,node[n].even); return ; } pushdown(n); LL mid=(node[n].l+node[n].r)>>1ll,L=n<<1ll,R=(n<<1ll)|1ll; if(r<=mid) update(l,r,add,L); else if(l>mid) update(l,r,add,R); else update(l,mid,add,L),update(mid+1ll,r,add,R); node[n].sum=node[L].sum+node[R].sum; node[n].odd=node[L].odd+node[R].odd; node[n].even=node[L].even+node[R].even;}void Search(LL l,LL r,LL n,char s)//查询{ if(node[n].l==l&&node[n].r==r) { if(s=='S') sum+=node[n].sum; else sum+=node[n].odd; return ; } pushdown(n); LL mid=(node[n].l+node[n].r)>>1ll,L=(n<<1ll),R=(n<<1ll)|1ll; if(r<=mid) Search(l,r,L,s); else if(l>mid) Search(l,r,R,s); else Search(l,mid,L,s),Search(mid+1ll,r,R,s);}int main(){ //freopen("Input.txt","r",stdin); //freopen("Output.txt","w",stdout); LL n,m; while(~scanf("%lld%lld",&n,&m)) { memset(x,0,sizeof(x)); memset(node,0,sizeof(node)); for(int i=1; i<=n; i++) scanf("%lld",&x[i]); build_tree(1ll,n,1ll); while(m--) { char s[5]; scanf("%s",s); if(s[0]=='A') { LL a,b,c; scanf("%lld%lld%lld",&a,&b,&c); update(a,b,c,1ll); } else { sum=0; LL a,b; scanf("%lld%lld",&a,&b); Search(a,b,1ll,s[0]); printf("%lld\n",sum); } } }}
0 0
- 线段树?线段树!
- 线段树?线段树!
- 线段_线段树
- 线段_线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 位图的应用之海量数据查找
- Java Logger(java日志)
- 生成二维码 并展示在ImagView中
- python上传文件到ftp服务器
- CorelDRAW中的版面样式和标签样式该如何运用
- 线段树
- 正交函数(orthogonal functions)
- AutoCAD 2000-14的序列号大全
- CGLib动态代理原理及实现
- c# 第二章 课后习题3
- memcpy函数 & 使用泛型指针交换任何类型数据
- memset函数的作用
- Oracle12c日常pdb创建、开关和删除操作
- (DT系列一)DTS结构及其编译方法