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

来源:互联网 发布:烈火战神 完整源码 编辑:程序博客网 时间:2024/05/22 14:18

#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;
}

 

原创粉丝点击