POJ 3225

来源:互联网 发布:西南财经网络教育 编辑:程序博客网 时间:2024/05/21 06:52

POJ 3225

有中文题意,不用多说,以前刚学线段树的时候曾经做过,不过死活做不过来,现在还是无限TLE,实在没办法了,稍微去瞄了其他人的代码,豁然开朗啊,稍微修改一下就AC了。

有5种操作,实质上针对线段树,只有2种操作,1是更新,二是翻转。

U : 更新a,b段为1。

I : 更新除a,b段之外的所有区间为0。

D :更新a,b段为0。

C : 翻转a,b段,a,b段之外的区间更新为0。

S : 翻转a,b段。

将整数以外的每个区间都看成一个整数,就可以建立一个65535*2 + 1长度的线段树。线段树保存2个值,一个是更新值,一个是翻转次数。每作一次更新操作时候,更新的区间的翻转次数要清0,翻转操作时候,只需要将区间操作数+1,等输入完毕后再一次过处理,就可以大大省略时间,就是蠢在这里了,连翻转每次都处理一次。

 

#include<iostream>#include<cstring>#include<cmath>#include<algorithm>#include<stdio.h>#include<string>#include<cstring>#include<map>#include<vector>#include<set>using namespace std;#define LL long long#define inf 0x7ffffff#define L(x) x<<1#define R(x) x<<1|1#define M(x,y) (x + y)>>1#define B(x) x>>1#define N 150000int flag[N];char x,l,z,r;int a,b,y;struct st{int l,r;int nots;int mark;}t[N*4];void change(int n,int l,int r);void build(int n,int l,int r){t[n].l = l;t[n].r = r;t[n].mark = t[n].nots = 0;if(l == r)return ;int mid = M(l,r);build(L(n),l,mid);build(R(n),mid + 1,r);}void clear(int n){if(t[n].l != t[n].r){t[L(n)].nots = t[R(n)].nots = -1;}}void down(int n){if(t[n].mark != -1){t[L(n)].mark = t[R(n)].mark = t[n].mark;t[n].mark = -1;}if(t[n].nots == -1){t[L(n)].nots = t[R(n)].nots = -1;t[n].nots = 0;}else{if(t[L(n)].nots == -1){t[L(n)].nots = t[n].nots;clear(L(n));}elset[L(n)].nots += t[n].nots;if(t[R(n)].nots == -1){t[R(n)].nots = t[n].nots;clear(R(n));}elset[R(n)].nots += t[n].nots;t[n].nots = 0;}}void up(int n){if(t[L(n)].mark == t[R(n)].mark && t[L(n)].mark != -1 ){t[n].mark = t[L(n)].mark;}}void renew(int n,int l,int r,int v){if(t[n].l >= l && t[n].r <= r ){t[n].mark = v;t[n].nots = -1;return ;}down(n);int mid = M(t[n].l,t[n].r);if(l <= mid)renew(L(n),l,r,v);if(r > mid)renew(R(n),l,r,v);up(n);}void change(int n,int l,int r){if(t[n].l >= l && t[n].r <= r){if(t[n].nots == -1){t[n].nots = 1;if(t[n].l != t[n].r){t[L(n)].l = t[R(n)].r = -1;}}elset[n].nots ++;return ;}down(n);int mid = M(t[n].l,t[n].r);if(l <= mid)change(L(n),l,r);if(r > mid)change(R(n),l,r);up(n);}void deal(int n){if(t[n].l == t[n].r){flag[t[n].l] = (t[n].mark + t[n].nots)%2;return ;}down(n);deal(L(n));deal(R(n));}void show(){int y = -1;for(int i = 0,a = b = -1;i <= 65535*2;i++){if(flag[i] == 1){if(a == -1){a = b = i;}elseb++;}else{if(a != -1){if(y == -1){y = 1;}elseprintf(" ");if(a%2 == 0)printf("[%d,",a/2);elseprintf("(%d,",a/2);if(b%2 == 0)printf("%d]",b/2);elseprintf("%d)",(b + 1)/2);}a = b = -1;}}if(y == -1)puts("empty set");elseprintf("\n");}int main(){int a,b;memset(flag , 0, sizeof(flag));build(1,0,65535*2);while( cin>>x ){cin>>l;scanf("%d,%d",&a,&b);cin>>r;a = a*2;b = b*2;if(l == '(')a++;if(r == ')')b--;if(a > b)continue;if(x == 'U'){renew(1,a,b,1);}if(x == 'I'){if(a != 0)renew(1,0,a - 1,0);if(b != 65535*2)renew(1,b + 1,65535*2,0);}if(x == 'D'){renew(1,a,b,0);}if(x == 'C'){if(a != 0)renew(1,0,a - 1,0);if(b != 65535*2)renew(1,b + 1,65535*2,0);change(1,a,b);}if(x == 'S'){change(1,a,b);}}deal(1);show();return 0;}