打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
POJ - 3225 Help with Intervals (区间置0/1与区间异或混合操作)

Help with Intervals

LogLoader, Inc. is a company specialized in providing products for analyzing logs. While Ikki is working on graduation design, he is also engaged in an internship at LogLoader. Among his tasks, one is to write a module for manipulating time intervals, which have confused him a lot. Now he badly needs your help.

In discrete mathematics, you have studied several basic set operations, namely union, intersection, relative complementation and symmetric difference, which naturally apply to the specialization of sets as intervals.. For your quick reference they are summarized in the table below:

OperationNotation

Definition

UnionA ∪ B{x : x ∈ A or x ∈ B}
IntersectionA ∩ B{x : x ∈ A and x ∈ B}
Relative complementationA − B{x : x ∈ A but B}
Symmetric differenceA ⊕ B(A − B) ∪ (B − A)

Ikki has abstracted the interval operations emerging from his job as a tiny programming language. He wants you to implement an interpreter for him. The language maintains a set S, which starts out empty and is modified as specified by the following commands:

CommandSemantics
U TS ← S ∪ T
I TS ← S ∩ T
D TS ← S − T
C TS ← T − S
S TS ← S ⊕ T

Input

The input contains exactly one test case, which consists of between 0 and 65,535 (inclusive) commands of the language. Each command occupies a single line and appears like

X T

where X is one of ‘U’, ‘I’, ‘D’, ‘C’ and ‘S’ and T is an interval in one of the forms (a,b)(a,b][a,b) and [a,b] (ab ∈ Z, 0 ≤ a ≤ b ≤ 65,535), which take their usual meanings. The commands are executed in the order they appear in the input.

End of file (EOF) indicates the end of input.

Output

Output the set S as it is after the last command is executed as the union of a minimal collection of disjoint intervals. The intervals should be printed on one line separated by single spaces and appear in increasing order of their endpoints. If S is empty, just print “empty set” and nothing else.

Sample Input

U [1,5]D [3,3]S [2,4]C (1,5)I (2,3]

Sample Output

(2,3)

题意:让模拟并、交、相对补、对称差。每一次都给定一个区间和操作类型,问最后区间是什么样子,用并的方式输出

思路:首先是括号'[' 和 '(' 的问题,这表明更新时 是更新一个区间,而不是区间上的端点,所以需要新插入一个点代表两点之前的段。 由于点是从 0 开始的,我采用的操作是  如端点 l , 先 l,然后以 2 * l - 1 作为线段树的更新端点,这样原每两个相邻的点之间就会插入一个点。

  • 并:直接将 更新区间置1
  • 交:将更新区间的两边置0
  • 相对补:两边置0,更新区间所有值取异或
  • 对称差:更新区间所有值取异或

我一开始,只设置了一个 type 数组,表示区间是否是同一值。利用 type 直接更新到值相同的段,然后 T 了。

搜了一下题解,还需要用到 lazyXor 数组。

唯一 一个需要很理解的地方就是:如果当前区间是同一值,就对 type 数组操作 (因为最后查询的时候是查询 type 是否为 1),否则就只能对 lazyXor 操作。   对于 push_down 时,type 的优先级要大于 lazyXor,也就是 如果能够利用 type 进行push_down,就用type,同时还要将两个儿子的 lazyXor 置0 (因为这是直接赋值的,且type != -1 时,这个区间的 lazyXor 一定为 0)。置 0/1 时也要将 lazyXor 置0

贴上抄袭代码:

#include<cstdio>#include<cstring>#include<iostream>#define debug(x) cout << "[" << #x <<": " << (x) <<"]"<< endl#define pii pair<int,int>#define clr(a,b) memset((a),b,sizeof(a))#define rep(i,a,b) for(int i = a;i < b;i   )#define pb push_back#define MP make_pair#define LL long long#define ull unsigned LL#define ls i << 1#define rs (i << 1)   1#pragma GCC optimize(2)#define INT(t) int t; scanf("%d",&t)using namespace std;const int maxn = 65536 * 2   10;int type[maxn << 2];int lazyXor[maxn << 2];const int n = 65536 * 2 - 1;void solve(int i){    if(type[i] != -1){        type[i] ^= 1;        lazyXor[i] = 0;    }    else lazyXor[i] ^= 1;}void push_down(int l,int r,int i){    if(type[i] != -1){        type[ls] = type[rs] = type[i];        lazyXor[ls] = lazyXor[rs] = 0;        type[i] = -1;    }    else if(lazyXor[i] == 1){        solve(ls);        solve(rs);        lazyXor[i] = 0;    }}void update(int l,int r,int ul,int ur,int i,int UorI){    if(ul > ur) return ;    if(ul <= l && r <= ur){        type[i] = UorI;        lazyXor[i] = 0;        return ;    }    push_down(l,r,i);    int mid = (l   r) >> 1;    if(ul <= mid) update(l,mid,ul,ur,i << 1,UorI);    if(ur > mid) update(mid   1,r,ul,ur,i << 1 | 1,UorI);    type[i] = (type[i << 1] == type[i << 1 | 1] ? type[i << 1] : -1);}void updateC(int l,int r,int ul,int ur,int i){    if(ul > ur) return ;    if(ul <= l && r <= ur){        solve(i);        return ;    }    if(l == r) return ;    push_down(l,r,i);    int mid = (l   r) >> 1;    if(ul <= mid) updateC(l,mid,ul,ur,i << 1);    if(ur > mid) updateC(mid   1,r,ul,ur,i << 1 | 1);}#define ok(x) (2 * (x) - 1)bool query(int l,int r,int pos,int i){    if(l == r)        return type[i] == 1;    push_down(l,r,i);    int mid = (l   r) >> 1;    if(pos <= mid) return query(l,mid,pos,i << 1);    if(pos > mid) return query(mid   1,r,pos,i << 1 | 1);}int main() {    char ch;    while(~scanf("%c",&ch)){        char lef,rig;        int l,r;        scanf(" %c%d,%d%c",&lef,&l,&r,&rig);           l;    r;        l = ok(l);        r = ok(r);        if(ch == 'U'){            if(lef == '(')    l;            if(rig == ')') -- r;            update(1,n,l,r,1,1);/// 把中间的直接变成1        }        else if(ch == 'I'){     /// 把两边的全部变成0            if(lef == '[') -- l;            if(rig == ']')    r;            update(1,n,1,l,1,0);            update(1,n,r,n,1,0);        }        else if(ch == 'D'){            if(lef == '(')    l;            if(rig == ')') -- r;            update(1,n,l,r,1,0);        }        else if(ch == 'C'){            if(lef == '[') -- l;            if(rig == ']')    r;            update(1,n,1,l,1,0);            update(1,n,r,n,1,0);               l;            -- r;            updateC(1,n,l,r,1);        }        else {            if(lef == '(')    l;            if(rig == ')') -- r;            updateC(1,n,l,r,1);        }        getchar();    }    int coun = 0;        int Beg = maxn,END;        char Lef,Rig;        for(register int i = 1;i <= n   1;   i){            int tttmp = i == n   1 ? 0 : query(1,n,i,1);            if(tttmp){                END = (i   1) / 2 - 1;                Rig = i % 2 == 1 ? ']':')';                if(Beg > END){                    Beg = END;                    Lef = i % 2 == 1 ? '[':'(';                }                   coun;            }            else if(!tttmp || i == n   1){                if(coun && Beg != maxn) printf("%c%d,%d%c ",Lef,Beg,END   (i % 2 == 1),Rig);                Beg = maxn;            }        }        if(coun == 0) printf("empty set");        printf("\n");    return 0;}

 

来源:https://www.icode9.com/content-4-329051.html
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Vlookup函数实例(全)
LABVIEW的深入探索之功能强大的位操作能力 来自 csxcs366的博客
聊一聊C语言位操作
求函数最值,一般方法和步骤,和你想的可能不一样
【几何画板教程】【智能函数】
线段树
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服