以后再也不信网上大神的翻译了
离散化,线段树,染色问题
附手动离散化和c++函数离散化
复杂度
O(N∗log2N)
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int MAXN = 10005 , MAXM = 20005;
int n , m;
int tot;
int tree[MAXM<<2] ,node[MAXM] , rank[MAXM] , sa[MAXM];
struct foldcolor{int l,r;}op[MAXN];
bool hash[MAXN];
inline void fold_down(const int si)
{
if(tree[si] != false)
{
tree[si<<1] = tree[(si<<1)|1] = tree[si];
tree[si] = false;
}
}
inline void insert(const int &col,const int l,const int r,const int ll,const int rr,const int si)
{
if(l == ll && r == rr)
{
tree[si] = col;
}
else
{
fold_down(si);
int mid = (ll + rr)>>1;
if(l > mid)
insert(col,l,r,mid+1,rr,(si<<1)|1);
else if(r <= mid)
insert(col,l,r,ll,mid, si<<1);
else
{
insert(col,l,mid,ll,mid, si<<1 );
insert(col,mid+1,r,mid+1,rr,(si<<1)|1);
}
}
}
inline void ans_count(const int ll,const int rr,const int si)
{
if(ll == rr)
{
if(tree[si] && hash[tree[si]]==false)
{tot ++;hash[tree[si]]=true;}
}
else
{
int mid = (ll + rr)>>1;
fold_down(si);
ans_count(ll,mid,(si<<1));
ans_count(mid+1,rr,(si<<1)|1);
}
}
bool cmp(const int &a,const int &b)
{
return (node[a] < node[b]);
}
int main()
{
int T;
#ifndef ONLINE_JUDGE
freopen("poj2528.in","r",stdin);
freopen("poj2528.out","w",stdout);
#endif
scanf("%d",&T);
while(T--)
{
memset(node,0,sizeof(node));
memset(hash,false,sizeof(hash));
memset(tree,0,sizeof(tree));
scanf("%d",&n);
tree[1] = 0;
for(int i = 1;i <= n;i++)
{
scanf("%d%d",&op[i].l,&op[i].r);
node[(i<<1)-1]=op[i].l, node[(i<<1)]=op[i].r;
}
m = n<<1;
for(int i = 1;i <= m;i++)rank[i] = i;
sort(rank+1 ,rank+m+1,cmp);
sa[rank[1]] = 1;
for(int i = 2;i <= m;i++)
{
sa[rank[i]]=sa[rank[i-1]]+(node[rank[i]]!=node[rank[i-1]]);
}
m = sa[rank[m]];
for(int i = 1;i <= n;i++)
{
insert(i,sa[(i<<1)-1],sa[(i<<1)],1,m,1);
}
tot = 0;
ans_count( 1, m, 1);
printf("%d\n",tot);
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
}
以上为手动离散化
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int MAXN = 10005 , MAXM = 20005;
int n , m;
int tot;
int tree[MAXM<<2] ,node[MAXM];
struct foldcolor{int l,r;}op[MAXN];
bool hash[MAXN];
inline void fold_down(const int si)
{
if(tree[si] != false)
{
tree[si<<1] = tree[(si<<1)|1] = tree[si];
tree[si] = false;
}
}
inline void insert(const int &col,const int l,const int r,const int ll,const int rr,const int si)
{
if(l == ll && r == rr)
{
tree[si] = col;
}
else
{
fold_down(si);
int mid = (ll + rr)>>1;
if(l > mid)
insert(col,l,r,mid+1,rr,(si<<1)|1);
else if(r <= mid)
insert(col,l,r,ll,mid, si<<1);
else
{
insert(col,l,mid,ll,mid, si<<1 );
insert(col,mid+1,r,mid+1,rr,(si<<1)|1);
}
}
}
inline void ans_count(const int ll,const int rr,const int si)
{
if(ll == rr)
{
if(tree[si] && hash[tree[si]]==false)
{tot ++;hash[tree[si]]=true;}
}
else
{
int mid = (ll + rr)>>1;
fold_down(si);
ans_count(ll,mid,(si<<1));
ans_count(mid+1,rr,(si<<1)|1);
}
}
bool cmp(const int &a,const int &b)
{
return (node[a] < node[b]);
}
int main()
{
int T;
#ifndef ONLINE_JUDGE
freopen("poj2528.in","r",stdin);
freopen("poj2528.out","w",stdout);
#endif
scanf("%d",&T);
while(T--)
{
memset(node,0,sizeof(node));
memset(hash,false,sizeof(hash));
memset(tree,0,sizeof(tree));
scanf("%d",&n);
tree[1] = 0;
for(int i = 1;i <= n;i++)
{
scanf("%d%d",&op[i].l,&op[i].r);
node[(i<<1)-1]=op[i].l, node[(i<<1)]=op[i].r;
}
m = n<<1;
sort(node + 1, node + m + 1);
m = unique(node + 1, node + m +1) - (node + 1);
for(int i = 1;i <= n;i++)
{
op[i].l = lower_bound(node+1 , node + m +1 ,op[i].l) - node;
op[i].r = lower_bound(node+1 , node + m +1, op[i].r) - node;
insert(i,op[i].l,op[i].r,1,m,1);
}
tot = 0;
ans_count( 1, m, 1);
printf("%d\n",tot);
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
}
于是发现c++的离散化真好写