您的位置:首页 > 其它

PKU 2528 Mayor's posters离散的线段树

2010-03-19 20:11 295 查看
#include <iostream>
#include<stdio.h>
#include <algorithm>
using namespace std;
const int N=20010;/*是PKU耍无赖还是我本身开的太小啊,我原本是10010的后面的都是10*N的,结果都是RE,唯有把N=20010才过,求解!!!!!*/

int mark[10*N];
struct tree
{
int l,r;//是离散化的点的位次
int turn;
}t[8*N*4];

struct Point
{
int beg,end;
int turn;
}dia[N*10];

int node[10*N];
int all;

void maketree(int c,int l,int r)
{
t[c].l = l;
t[c].r = r;
t[c].turn = 0;
if(l==r)
{
return ;
}
int mid = (l+r)>>1;
maketree(c*2,l,mid);
maketree(2*c+1,mid+1,r);
}

void update(int c,int l,int r,int turn)
{
if(t[c].l>=l && t[c].r<=r)
{
t[c].turn = turn;
return ;
}
if(t[c].turn != 0)
{
t[2*c].turn = t[2*c+1].turn = t[c].turn;
t[c].turn = 0;
}
int mid = (t[c].l + t[c].r) >> 1;
if(r<=mid)
update(2*c,l,r,turn);
else if(l>mid)
update(2*c+1,l,r,turn);
else
{
update(2*c,l,mid,turn);
update(2*c+1,mid+1,r,turn);
}
}

void findans(int c)
{
if(t[c].turn != 0 || t[c].l == t[c].r)
{
mark[t[c].turn] = 1;
}
else
{
findans(c*2);
findans(c*2+1);
}
}

int f(int num)
{
int l=1,r=all;
while(l<=r)
{
int mid = (l+r)>>1;
if(num == node[mid])
return mid;
if(num < node[mid])
r = mid - 1;
else
l = mid + 1;
}
}

int main()
{
int n,i;
int ans=0;
int cnt = 1;
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d %d",&dia[i].beg,&dia[i].end);
dia[i].turn = i+1;
node[cnt++] = dia[i].beg;
node[cnt++] = dia[i].end;
mark[i+1] = 0;
}
sort(node+1,node+cnt);
all = 1;
for(i=2;i<cnt;i++)
{
while(i < cnt && node[i] == node[i-1]) i++;
if(i!=cnt)
node[++all] = node[i];
}
maketree(1,1,all);
for(i=0;i<n;i++)
{
int b=f(dia[i].beg);
int e=f(dia[i].end);
//cout << b << " " << e <<endl;
update(1,b,e,dia[i].turn);
}
int sum = 0;
findans(1);
for(i=1;i<=n;i++)
if(mark[i])
sum ++;
printf("%d/n",sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: