poj 3225(线段树)
来源:互联网 发布:vue.js 分页插件 编辑:程序博客网 时间:2024/05/22 02:30
题目链接:http://poj.org/problem?id=3225
题意描述:给你一个集合初始化为空集,然后让它和其他集合进行一系列操作,最后输出操作之后的集合,集合操作有U表示求并集,I表示求交集,D表示S与给出集合求差集,C表示给出集合与S的集合求差集,这里的区间有开有并
分析:假设不考虑区间的开与闭,用线段树来维护所有区间初始化为0
如果是U的话则将(l,r)的值赋值为1
如果是I的话则将(0,l-1)和(r+1,max)的值赋值为1
如果是D的话则将(l,r)赋值为0
如果是C的话则将(0,l-1)(r+1,max)的值赋值为0,将区间(l,r)的区间取反
如果是S的话则将(l,r)区间取反
但是这样都是建立在点树的基础上的,但这里单位区间和点都应该看成点,这里就需要一个转换左闭区间转换为点2*l,将左开区间转换为2*r+1,将右闭区间转换为2*r,将右开区间转换为2*r-1,那么这样之后所有的单位区间为一个点,点也是一个点,这样就可以用线段树来维护啦,具体见代码:
#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int N=65535*2;struct node{ int l,r; int tag; int num;}tree[N*4];bool vis[N];void bulid (int rt, int l , int r){ tree[rt].l=l; tree[rt].r=r; tree[rt].tag=0; tree[rt].num=0; if(l==r)return; int mid=(l+r)>>1; bulid(2*rt,l,mid); bulid(2*rt+1,mid+1,r);}void pushdown(int rt){ if(tree[rt].tag!=-1) { tree[2*rt].tag=tree[rt].tag; tree[2*rt+1].tag=tree[rt].tag; tree[rt].tag=-1; tree[2*rt].num=tree[2*rt+1].num=tree[rt].num=0; } if(tree[rt].num) { if(tree[2*rt].num) tree[2*rt].num=0; else if(tree[2*rt].tag!=-1) tree[2*rt].tag^=1; else tree[2*rt].num=1; if(tree[2*rt+1].num)tree[2*rt+1].num=0; else if(tree[2*rt+1].tag!=-1) tree[2*rt+1].tag^=1; else tree[2*rt+1].num=1; tree[rt].num=0; }}void insert(int rt, int l , int r, int op){ //if(tree[rt].l>l||tree[rt].r<r)return; if(op<2) { if(tree[rt].l==l&&tree[rt].r==r) { tree[rt].tag=op; tree[rt].num=0; return; } } else if(op==2) { if(l==tree[rt].l && r==tree[rt].r) { if(tree[rt].tag!=-1) tree[rt].tag^=1; else tree[rt].num^=1; return; } } int mid=(tree[rt].l+tree[rt].r)>>1; pushdown(rt); if(r<=mid)insert(2*rt,l,r,op); else if(l>mid)insert(2*rt+1,l,r,op); else {insert(2*rt,l,mid,op); insert(2*rt+1,mid+1,r,op);} if(tree[2*rt].tag==tree[2*rt+1].tag) tree[rt].tag=tree[2*rt].tag;}void quary(int rt){ if(tree[rt].l==tree[rt].r) { vis[tree[rt].l]=tree[rt].tag; return; } pushdown(rt); quary(2*rt); quary(2*rt+1);}int main (){ char op, ch1, ch2; int l,r,i,s; bulid(1,0,N); while(scanf("%c %c%d,%d%c",&op,&ch1,&l,&r,&ch2)!=EOF) { getchar(); l=l+l; r=r+r; if(ch1=='(') l++; if(ch2==')') r--; if(l>r)continue; switch(op) { case 'U': insert(1,l,r,1);break; case 'I': if(l>0) insert(1,0,l-1,0); if(r<N) insert(1,r+1,N,0);break; case 'D': insert(1,l,r,0);break; case 'C': if(l>0) insert(1,0,l-1,0); if(r<N) insert(1,r+1,N,0); insert(1,l,r,2);break; case 'S': insert(1,l,r,2);break; } } quary(1); int begin, end, tmp = 1; for(i = 0; i <= N; i++) { while(i <= N && !vis[i]) i++; begin = i; if(i > N) break; while(i <= N && vis[i]) i++; end = i - 1; tmp = 0; if(begin&1) printf("(%d,", begin/2); else printf("[%d,", begin/2); if(end&1) printf("%d) ", (end+1)/2); else printf("%d] ", end/2); } if(tmp) printf("empty set"); printf("\n"); return 0;}
- poj 3225(线段树)
- poj 3225(线段树)
- 线段树重开poj 3225
- POJ 3225 Help with Intervals 线段树
- POJ 3225 Help with Intervals 线段树
- POJ 3225 Help with Intervals 线段树
- poj 3225 Help with Intervals[线段树]
- POJ-3225 Help with Intervals 线段树
- poj 3225 线段树注意lazy标记
- POJ 3225 Help with Intervals (线段树)
- poj 3225 线段树 经典题
- poj 3225 Help with Intervals (线段树)
- poj 3225 Help with Intervals(线段树)
- POJ 3225 Help with Intervals 线段树
- POJ 3225 线段树+lazy标记
- POJ 3225 Help with Intervals 【线段树】
- POJ 2777 线段树
- poj 3468 线段树
- 求连续子数组的最大和O(n)解法之思路与Java实现
- ASP.NET4种事务
- C++中的函数指针和函数对象总结
- could not initialize proxy - no Session
- 二叉树的左旋和右旋
- poj 3225(线段树)
- IE8 开发人员工具 自动打开
- 苹果iPhone 5 4S发布会现场实录
- UCWeb印度市场份额超两成 宣布进军北美市场
- 关于bash命令
- VMWare Workstation 8 requires CPU support X64 technique
- POJ 1325 二分图最小点集覆盖
- 这些怎么区别?(*(char **(*)(char **,char **))0)(char **,char **)
- 阿里巴巴公司DBA笔试题及参考答案