您的位置:首页 > 其它

poj 3225 线段树 经典题

2014-03-03 19:47 330 查看
泪奔。。。

终于A拉。

网上已经有很多的题解了。。。

就不详细描述了。

集合的操作还是蛮有趣的。

线段树原来可以这么灵活啊

0 1 的覆盖即使有区间操作也用不着重新写个标记

还有 线段树 中 如果操作的是区间的话 (端点和内部的点都有意义) 那么点的数量扩大两倍。

经过一题。。感觉线段树的 level 又提升了呢。。

#include <stdio.h>
#include <iostream>
#include <queue>
#include <algorithm>
#include <map>
#include <vector>
#include <cmath>
#include <string.h>
using namespace std;

#define ll long long

#define PII pair<int,int>
#define PDI pair<double,int>
#define fst first
#define sec second
#define MS(x,d) memset(x,d,sizeof(x))
#define INF 0x3f3f3f3f
#define ALL(x) x.begin(),x.end()
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define MAX 140000
#define ROOT 0,MAX,1
#define READ freopen("acm.in","r",stdin)

int data[((MAX)<<2)+100];
int col[((MAX)<<2)+100];

void PushDown(int rt)
{
if(data[rt]!=-1)
{
col[rt]=0;
col[rt<<1]=col[rt<<1|1]=0;
data[rt<<1]=data[rt<<1|1]=data[rt];
}
else if(col[rt])
{
if(data[rt<<1]==-1)
col[rt<<1]^=1;
else
col[rt<<1]=0,data[rt<<1]^=1;

if(data[rt<<1|1]==-1)
col[rt<<1|1]^=1;
else
col[rt<<1|1]=0,data[rt<<1|1]^=1;
col[rt]=0;
}
}
void PushUP(int rt)
{
if(data[rt<<1]==data[rt<<1|1])
data[rt]=data[rt<<1];
else
data[rt]=-1;
}
// 1 0 2 1 3 ^
void update(int L,int R,int op,int l,int r,int rt)
{
if(L>r||R<l)
return ;
if(L<=l&&r<=R)
{
if(op==3&&data[rt]==-1)
{
col[rt]^=1;
}
else if(op==3&&data[rt]!=-1)
{
data[rt]^=1;
col[rt]=0;
}
if(op==1)
{
col[rt]=0;
data[rt]=0;
}
if(op==2)
{
col[rt]=0;
data[rt]=1;
}
//printf("%d %d %d %d %d\n",L, R, l, r, data[rt]);

return ;
}
PushDown(rt);
int m=(l+r)>>1;
update(L,R,op,lson);
update(L,R,op,rson);
PushUP(rt);
}
int query(int P,int l,int r,int rt)
{
if(l==r)
return data[rt];
int m=(l+r)>>1;
PushDown(rt);
if(P<=m)
return query(P,lson);
else
return query(P,rson);
PushUP(rt);
}
// even is end point, odd is not
void getLR(int &l,int &r,char lb,char rb)
{
l*=2,r*=2;
if(lb=='(')
l++;
if(rb==')')
r--;
}
int main()
{
READ;
char op[4];
char s[500];
while(scanf("%s%s",op,s)!=EOF)
{
int l,r;
char lb,rb;
sscanf(s,"%c%d,%d%c",&lb,&l,&r,&rb);
// l++,r++;
getLR(l,r,lb,rb);
// cout<<l<<" "<<r<<endl;
switch(op[0])
{
case 'U':
update(l,r,2,ROOT);
break;
case 'I':
update(0,l-1,1,ROOT);
update(r+1,MAX,1,ROOT);
break;
case 'D':
update(l,r,1,ROOT);
break;
case 'C':
update(0,l-1,1,ROOT);
update(r+1,MAX,1,ROOT);
update(l,r,3,ROOT);
break;
case 'S':
update(l,r,3,ROOT);
break;
default :
break;
}
}
bool flag=false;
int cnt=0;
for(int i=0;i<MAX;i++)
{
int res=query(i,ROOT);
if(!flag&&res==1)
{
cnt++;
if(i%2)
cout<<'(';
else
cout<<'[';
cout<<i/2;
flag=true;
}
else if(flag&&res==0)
{
int t=i-1;
cout<<','<<i/2;
if(t%2)
cout<<')';
else
cout<<']';
cout<<" ";
flag=false;
}
}
if(!cnt)
cout<<"empty set"<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: