| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 47849 | Accepted: 13894 |
Description
Input
Output

Sample Input
1 5 1 4 2 6 8 10 3 4 7 10
Sample Output
4
这道题可以用线段树做,记录每一段的涂色情况,没有涂色则为0,多种颜色则为-1,一种颜色则为value。这里离散化的时候要注意如果排序后两个数大于1,那么要在中间加一个数,如数据3 3,7 3,4 6,7,那么离散化的时候要1,2,3,4,5.不然颜色只有2中,中间的4-6会被覆盖。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
int pos[80005],a[10006],c[10005],m,sum[80006],s[80006],k;
struct node{
int l,r,ans;
}b[16*10005];
void build(int l,int r,int i)
{
int mid;
b[i].l=l;b[i].r=r;b[i].ans=0;
if(l==r)return;
mid=(l+r)/2;
build(l,mid,i*2);
build(mid+1,r,i*2+1);
}
void update(int l,int r,int value,int i)
{
int mid;
if(b[i].l==l && b[i].r==r){
b[i].ans=value;return;
}
if(b[i].ans>0){
b[i*2].ans=b[i*2+1].ans=b[i].ans;
}
b[i].ans=-1;
mid=(b[i].l+b[i].r)/2;
if(r<=mid)update(l,r,value,i*2);
else if(l>mid)update(l,r,value,i*2+1);
else {
update(l,mid,value,i*2);
update(mid+1,r,value,i*2+1);
}
}
void question(int i)
{
int mid;
if(b[i].ans>0){
sum[++k]=b[i].ans;return;
}
if(b[i].ans==0 || (b[i].l==b[i].r))return;
else {
question(i*2);question(i*2+1);
}
}
int find(int x)
{
int l=1,r=m,mid;
while(l<=r){
mid=(l+r)/2;
if(pos[mid]>x)r=mid-1;
else if(pos[mid]<x)l=mid+1;
else return mid;
}
if(pos[l]==x)return l;
else return r;
}
int main()
{
int n,i,j,T,l,r,num;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d%d",&a[i],&c[i]);
s[i]=a[i];s[i+n]=c[i];
}
sort(s+1,s+1+2*n);
m=1;pos[1]=s[1];
for(i=2;i<=2*n;i++){
if(s[i]!=s[i-1]){
if(s[i]-s[i-1]>1){
m++;pos[m]=s[i-1]+1;
}
m++;pos[m]=s[i];
}
}
build(1,m,1);
for(i=1;i<=n;i++){
l=find(a[i]);
r=find(c[i]);
update(l,r,i,1);
}
k=0;
question(1);
sort(sum+1,sum+1+k);
num=1;
for(i=2;i<=k;i++){
if(sum[i]!=sum[i-1])num++;
}
printf("%d\n",num);
}
return 0;
}原文:http://blog.csdn.net/kirito_acmer/article/details/46006439