Help with Intervals(集合的交并补,线段树)
很早以前做过这题,早就没印象了,估计当时也是照着某大神的代码抄过的,现在是连题意都看了好长时间。
刚开始的S集合是空集,给你一些操作和一个T集合,把操作的结果再赋给S集合。
解法:因为会有开区间和闭区间,对于一个值我拆成了两个点 比如 1,2,3, 表示的区间为[1,2] 把两个端点值分别设为2个点,把端点之间的区间也设为一个点,那么 区间就可以表示为(1,2) = 1,[1,2) = 1,2 (1,2] = 2,3 ,把这些点建成树,然后进行区间的操作,也就转换成了对点的操作。
并操作,就是直接把a-b变为1.
S-T 操作。 直接把T的区间段变为0.
T-S 操作, 这个需要特别说明一下,因为这个操作的结果是把T之外的区间清零,把T这段区间的值变为相反的,这个不能用延迟覆盖来操作,需要加一个延迟标记,表示这段区间我需要逆置。
异或操作,异或操作的结果就是 T之外的区间不变化,T这段区间逆置,跟上面类似。
如果此段已有逆置的延迟标记,再加一个的话相当于抵消。
忘记判空集 ,WA一次。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 140000
#define M 132000
#define LL long long
#define INF 0xfffffff
const double eps = 1e-;
const double pi = acos(-1.0);
const double inf = ~0u>>;
int s[N<<],a[N],xlz[N<<],lz[N<<];
struct node
{
int l,r,f;
}p[N];
void down(int w,int m)
{
if(lz[w]!=-)
{
s[w<<] = s[w<<|] = lz[w<<] = lz[w<<|] = lz[w];
xlz[w<<] = xlz[w<<|] = ;
lz[w] = -;
}
if(xlz[w])
{
xlz[w<<] ^= ;
xlz[w<<|] ^= ;
xlz[w] = ;
}
}
void build(int l,int r,int w)
{
lz[w] = -;
xlz[w] = ;
s[w] = ;
if(l==r)
{
return ;
}
int m = (l+r)>>;
build(l,m,w<<);
build(m+,r,w<<|);
}
void update(int a,int b,int p,int d,int l,int r,int w)
{
if(a<=l&&b>=r)
{
//cout<<l<<" "<<r<<" "<<w<<endl;
if(p==)
{
s[w] = d;
lz[w] = d;
xlz[w] = ;
}
else
{
xlz[w] ^= ;
}
return;
}
down(w,r-l+);
int m = (l+r)>>;
if(a<=m) update(a,b,p,d,l,m,w<<);
if(b>m) update(a,b,p,d,m+,r,w<<|);
}
int query(int p,int l,int r,int w)
{
if(l==r)
{
if(xlz[w])
{
s[w]^=;
xlz[w] ^= ;
}
return s[w];
}
down(w,r-l+);
int m = (l+r)>>;
if(p<=m) return query(p,l,m,w<<);
else return query(p,m+,r,w<<|);
}
int main()
{
int x,y,i;
char sr[],c1,c2;
build(,M,);
while(scanf("%s",sr)!=EOF)
{
getchar();
scanf("%c%d,%d%c",&c1,&x,&y,&c2);
x = (c1=='['?*x+:*x+);
y = (c2==']'?*y+:*y);
if(sr[]=='U')
{
update(x,y,,,,M,);
}
else if(sr[]=='I')
{
if(x>)
update(,x-,,,,M,);
update(y+,M,,,,M,);
}
else if(sr[]=='D')
{
update(x,y,,,,M,);
}
else if(sr[]=='C')
{
if(x>)
update(,x-,,,,M,);
update(y+,M,,,,M,);
update(x,y,,,,M,);
}
else
{
update(x,y,,,,M,);
}
}
int g = ;
for(i = ; i <= M ;i++)
a[i] = query(i,,M,);
for(i = ; i <= M ; i++)
{
if(a[i]&&a[i]!=a[i-])
{
g++;
p[g].l = (i-)/;
p[g].f = (i%?:);
}
else if(a[i]!=a[i-])
{
p[g].r = (i-)/;
p[g].f+=((i-)%?:);
}
}
for(i = ; i <= g ;i++)
{
if(p[i].f==)
printf("(%d,%d)",p[i].l,p[i].r);
else if(p[i].f==)
printf("[%d,%d)",p[i].l,p[i].r);
else if(p[i].f==)
printf("(%d,%d]",p[i].l,p[i].r);
else
printf("[%d,%d]",p[i].l,p[i].r);
if(i!=g) printf(" ");
}
if(g==) puts("empty set");
else
puts("");
return ;
}
Help with Intervals(集合的交并补,线段树)的更多相关文章
- c++ 求集合的交并补
#include<iostream.h> #include<windows.h> #include<iomanip.h> #include<stdio.h&g ...
- java 集合交并补
通过使用泛型方法和Set来表达数学中的表达式:集合的交并补.在下面三个方法中都将第一个參数Set复制了一份,并未直接改动參数中Set. package Set; import java.util.Ha ...
- 2019南昌网络赛-I(单调栈+线段树)
题目链接:https://nanti.jisuanke.com/t/38228 题意:定义一段区间的值为该区间的和×该区间的最小值,求给定数组的最大的区间值. 思路:比赛时还不会线段树,和队友在这题上 ...
- bzoj4399 魔法少女LJJ 线段树合并+线段树二分+并查集
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4399 题解 毒瘤题 \(9\) 种操作还有支持动态图的连通性 仔细读题 $ c<=7$. ...
- poj 3225 Help with Intervals(线段树,区间更新)
Help with Intervals Time Limit: 6000MS Memory Limit: 131072K Total Submissions: 12474 Accepted: ...
- 线段树(区间操作) POJ 3325 Help with Intervals
题目传送门 题意:四种集合的操作,对应区间的01,问最后存在集合存在的区间. 分析:U T [l, r]填充1; I T [0, l), (r, N]填充0; D T [l, r]填充0; C T[0 ...
- POJ 3225 Help with Intervals --线段树区间操作
题意:给你一些区间操作,让你输出最后得出的区间. 解法:区间操作的经典题,借鉴了网上的倍增算法,每次将区间乘以2,然后根据区间开闭情况做微调,这样可以有效处理开闭区间问题. 线段树维护两个值: cov ...
- Codeforces Gym 100231B Intervals 线段树+二分+贪心
Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...
- 培训补坑(day7:线段树的区间修改与运用)(day6是测试,测试题解以后补坑QAQ)
补坑咯~ 今天围绕的是一个神奇的数据结构:线段树.(感觉叫做区间树也挺科学的.) 线段树,顾名思义就是用来查找一段区间内的最大值,最小值,区间和等等元素. 那么这个线段树有什么优势呢? 比如我们要多次 ...
随机推荐
- html5--3.13 表单的新增属性
html5--3.13 表单的新增属性 学习要点 掌握表单新增属性的使用 HTML5新增表单属性 之前课程中已经接触过的新增属性:autocomplete属性/autofocus属性/list属性/m ...
- socket.io emit 常见用法
io.on('connect', onConnect); function onConnect(socket){ // 只发给sender. sending to the client socket. ...
- Asterisk 拨号方案中截取字符串
在dialplan中要截取字符串可用如下几种方式: 1.转到agi中由php进行处理,这种方法比较简单,在这里不再缀述 2.在dialplan中利用内置的方法进行截取 如 [test] exten = ...
- POJ1904(有向图缩点+输入输出挂参考)
King's Quest Time Limit: 15000MS Memory Limit: 65536K Total Submissions: 8311 Accepted: 3017 Cas ...
- JQuery扩展插件Validate—5添加自定义验证方法
从前面的示例中不难看出validate中自带的验证方法足以满足一般的要求,对于特别的要求可以使用addMethod(name,method,message)添加自定义的验证规则,下面的示例中添加了一个 ...
- SSIS 导入多个Excel 数据
http://blog.csdn.net/jinjazz/article/details/2710169 http://blog.csdn.net/jinjazz/article/details/27 ...
- html+css构成的框架,可自行改造
运行效果 代码下载地址:http://pan.baidu.com/s/1eSeBh2E
- Python_中__init__和__new__的异同
1:__new__:它是创建对象时调用,会返回当前对象的一个实例: __init__:它是创建对象后调用,对当前对象的一些实例初始化,无返回值 代码示例: >>> class Dat ...
- Codeforces 1108E2 Array and Segments (Hard version) 差分, 暴力
Codeforces 1108E2 E2. Array and Segments (Hard version) Description: The only difference between eas ...
- c语言中#和##的用法
一.一般用法 我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起. 用法: #include<cstdio> #include<climits> using nam ...