POJ 2777 线段树
2016-06-28 20:54
585 查看
一道线段树。lazy标记+位运算……(第一次写这个什么lazy标记,抄了一发题解)
我们发现:“或”操作在这里用正合适。
原题请戳这里
晚上又写了一遍
很可惜,只刷到了Code Length第三… 省了一步建树。
我们发现:“或”操作在这里用正合适。
原题请戳这里
// by Sirius_Ren #include <cstdio> #include <algorithm> #define N 100010 using namespace std; int l,t,o,xx,yy,zz; char jy; struct segtree{int left,right,num,lazy;}tree[N*4]; void build(int l,int r,int pos){ tree[pos].left=l,tree[pos].right=r,tree[pos].num=2,tree[pos].lazy=false; if(l==r)return; int mid=(l+r)/2; build(l,mid,pos*2),build(mid+1,r,pos*2+1); } void push_down(int pos){ tree[pos*2].lazy=tree[pos*2+1].lazy=true; tree[pos*2+1].num=tree[pos*2].num=tree[pos].num; tree[pos].lazy=false; } void add(int pos){ if(tree[pos].left>=xx&&tree[pos].right<=yy){ tree[pos].lazy=true; tree[pos].num=(1<<zz); return; } if(tree[pos].lazy)push_down(pos); int mid=(tree[pos].left+tree[pos].right)/2; if(xx<=mid)add(pos*2); if(yy>mid)add(pos*2+1); tree[pos].num=tree[pos*2].num|tree[pos*2+1].num; } int query(int pos){ if(tree[pos].left>=xx&&tree[pos].right<=yy)return tree[pos].num; if(tree[pos].lazy)push_down(pos); int mid=(tree[pos].left+tree[pos].right)/2; if(xx>mid)return query(pos*2+1); else if(yy<=mid)return query(pos*2); else return query(pos*2+1)|query(pos*2); } int split(){ int sum=query(1),ans=0; while(sum/=2)if(sum%2)ans++; return ans; } int main() { scanf("%d%d%d",&l,&t,&o); build(1,l,1); for(int i=1;i<=o;i++){ scanf("\n%c%d%d",&jy,&xx,&yy); if(xx>yy)swap(xx,yy); if(jy=='C')scanf("%d",&zz),add(1); else printf("%d\n",split()); } }
晚上又写了一遍
很可惜,只刷到了Code Length第三… 省了一步建树。
#include <bitset> #include <cstdio> #include <algorithm> using namespace std; int L,o,xx=1,yy,zz=1,t[400001]; char jy; bitset<400001>B; void pd(int p){t[p*2]=t[p*2+1]=t[p];B[p*2]=B[p*2+1]=true;B[p]=false;} void add(int l,int r,int p){ if(l>=xx&&r<=yy){B[p]=1;t[p]=1<<zz-1;return;} if(B[p])pd(p); int m=(l+r)/2; if(xx<=m)add(l,m,p*2); if(yy>m)add(m+1,r,p*2+1); t[p]=t[p*2]|t[p*2+1]; } int q(int l,int r,int p){ if(xx<=l&&yy>=r)return t[p]; if(B[p])pd(p); int m=(l+r)/2; if(m<xx)return q(m+1,r,p*2+1); else if(m>=yy)return q(l,m,p*2); else return q(l,m,p*2)|q(m+1,r,p*2+1); } int main(){ scanf("%d%d%d",&L,&jy,&o); yy=L,add(1,L,1); while(o--){ scanf("\n%c%d%d",&jy,&xx,&yy); if(xx>yy)swap(xx,yy); if(jy=='C')scanf("%d",&zz),add(1,L,1); else{ int s=q(1,L,1),a=0; while(s){if(s%2)a++;s/=2;} printf("%d\n",a); } } }
相关文章推荐
- Flex Namespace的用法
- C#中struct和class的区别详解
- 深入剖析C++中的struct结构体字节对齐
- C++ 关于STL中sort()对struct排序的方法
- C# Struct的内存布局问题解答
- ajax使用不同namespace的action的方法
- 深入C++中struct与class的区别分析
- 浅析c与c++中struct的区别
- 浅谈几种常见语言的命名空间(Namespace)
- c++中struct使用注意事项
- 深入解析C#编程中struct所定义的结构
- thinkphp autoload 命名空间自定义 namespace
- PHP命名空间(namespace)的使用基础及示例
- php中namespace use用法实例分析
- 浅析JavaScript中命名空间namespace模式
- 浅析内存对齐与ANSI C中struct型数据的内存布局
- php读取二进制流(C语言结构体struct数据文件)的深入解析
- 详解C++程序中定义struct结构体的方法
- C++ namespace相关语法实例分析
- Go语言struct类型介绍