(以下轉)感謝它幫助我理解離散化
假如不離散化,那線段樹的上界是10^7,假如建一個那么大的線段樹的話。。。必然MLE。于是要考慮離散化。
離散化的目的就是要將線段的長度適當的縮小,但不破壞題意。
比如:
------ (1,6)
------------ (1,12 )
像這樣這樣的兩條線段,可以把它們看作:
-- (1,2)
--- ( 1,3 )
這樣,縮短了線段的長度,但是他們的覆蓋關系并沒有改變。
關鍵我們要重新給壓縮后的線段標記起點和終點。
按照通用的離散化方法。。。。
首先依次讀入線段端點坐標,存于post[MAXN][2]中,post[i][0]存第一條線段的起點,post[i][1]存第一條線段的終點,然后用一個結構題數組line[MAXN]記錄信息,hash[i].v記錄端點坐標,hash[i].line記錄這個點屬于哪條線段(用正負數表示,負數表示起點,正數表示終點)。假如有N條線段,就有2*N個端點。然后將hash數組排序,按照端點的坐標,從小到大排。接著要把線段賦予新的端點坐標了。從左到右按照遞增的次序,依次更新端點,假如2*N個點中,共有M個不同坐標的點,那么線段樹的范圍就是[1,M]。
1
#include<iostream>
2
#include<stdlib.h>
3
#define MAXN 10000
4
#define MAX_UNSIGEN 65536
5
#define mixcolor -1
6
using namespace std;
7
struct seg
8

{
9
int left,right;
10
int color;
11
};
12
struct structx
13

{
14
int v; //端點值
15
int line; //屬于哪條線段,-起,+終
16
};
17
18
seg Segtree[MAX_UNSIGEN+2]; //數
19
bool colortable[MAXN+1];
20
int post[MAXN][2]; //記錄輸入的poster位置,post[i][0]起點,post[i][0]終點
21
structx hash[2*MAXN+1]; //所有端點,對其排序,相當于一個映射表
22
23
void buildsegtree(int v,int l,int r)
24

{
25
26
Segtree[v].left=l;
27
Segtree[v].right=r;
28
Segtree[v].color=0;
29
if(l==r) return ;
30
31
int mid=(l+r)>>1; // div 2
32
buildsegtree(v*2,l,mid);
33
buildsegtree(v*2+1,mid+1,r);
34
}
35
36
void insertseg(int v,int l,int r,int c)
37

{
38
if(Segtree[v].left==l && Segtree[v].right==r)
39
{
40
Segtree[v].color=c;
41
return ;
42
}
43
//only one color
44
if(Segtree[v].color != mixcolor )
45
{
46
Segtree[2*v].color=Segtree[v].color;
47
Segtree[2*v+1].color=Segtree[v].color;
48
Segtree[v].color=mixcolor;
49
}
50
51
int mid=(Segtree[v].left + Segtree[v].right) >> 1 ;
52
53
if(r<=mid) insertseg(2*v,l,r,c);
54
else
55
if(mid<l) insertseg(2*v+1,l,r,c);
56
else
57
{
58
insertseg(2*v,l,mid,c);
59
insertseg(2*v+1,mid+1,r,c);
60
}
61
}
62
63
void count(int v ,int l,int r)
64

{
65
if(Segtree[v].color !=mixcolor )
66
{
67
colortable[Segtree[v].color]=true;
68
return ;
69
}
70
int mid=(Segtree[v].left + Segtree[v].right) >> 1;
71
if(r<=mid) count(2*v,l,r);
72
else if(mid<l) count(2*v+1,l,r);
73
else
74
{
75
count(2*v,l,mid);
76
count(2*v+1,mid+1,r);
77
}
78
}
79
80
int cmp(const void *a,const void *b)
81

{
82
return ((structx*)a)->v - ((structx*)b)->v;
83
}
84
85
int main()
86

{
87
int c,n,i,j,cnt,index;
88
scanf("%d",&c);
89
while(c--)
90
{
91
scanf("%d",&n);
92
93
for(i=0,j=0,index=1;i<n;i++)
94
{
95
scanf("%d%d",&post[i][0],&post[i][1]);
96
hash[j].v=post[i][0];hash[j++].line=-index;
97
hash[j].v=post[i][1];hash[j++].line=index++;
98
}
99
//j==2*n
100
//離散化
101
qsort(hash,j,sizeof(hash[0]),cmp);
102
post[-hash[0].line-1][0]=1;
103
for(i=1,index=1;i<j;i++)
104
{
105
if(hash[i].v!=hash[i-1].v) index++;
106
107
if(hash[i].line<0)
108
post[-hash[i].line-1][0]=index;
109
else post[hash[i].line-1][1]=index;
110
111
}
112
113
buildsegtree(1,1,index);
114
for(i=0;i<n;i++)
115
insertseg(1,post[i][0],post[i][1],i+1);
116
117
count(1,1,index);
118
cnt=0;
119
for(i=1;i<=MAXN;i++)
120
if(colortable[i]==true)
121
{
122
cnt++;
123
colortable[i]=false;
124
}
125
126
printf("%d\n",cnt);
127
128
}
129
return 0;
130
}
131
#include<iostream>2
#include<stdlib.h>3
#define MAXN 100004
#define MAX_UNSIGEN 655365
#define mixcolor -16
using namespace std;7
struct seg8


{9
int left,right;10
int color;11
};12
struct structx13


{14
int v; //端點值15
int line; //屬于哪條線段,-起,+終16
};17

18
seg Segtree[MAX_UNSIGEN+2]; //數19
bool colortable[MAXN+1];20
int post[MAXN][2]; //記錄輸入的poster位置,post[i][0]起點,post[i][0]終點21
structx hash[2*MAXN+1]; //所有端點,對其排序,相當于一個映射表22

23
void buildsegtree(int v,int l,int r)24


{25
26
Segtree[v].left=l;27
Segtree[v].right=r;28
Segtree[v].color=0;29
if(l==r) return ; 30

31
int mid=(l+r)>>1; // div 232
buildsegtree(v*2,l,mid);33
buildsegtree(v*2+1,mid+1,r);34
}35

36
void insertseg(int v,int l,int r,int c)37


{38
if(Segtree[v].left==l && Segtree[v].right==r)39

{40
Segtree[v].color=c;41
return ;42
}43
//only one color44
if(Segtree[v].color != mixcolor ) 45

{46
Segtree[2*v].color=Segtree[v].color;47
Segtree[2*v+1].color=Segtree[v].color;48
Segtree[v].color=mixcolor;49
}50
51
int mid=(Segtree[v].left + Segtree[v].right) >> 1 ;52

53
if(r<=mid) insertseg(2*v,l,r,c);54
else 55
if(mid<l) insertseg(2*v+1,l,r,c);56
else 57

{58
insertseg(2*v,l,mid,c);59
insertseg(2*v+1,mid+1,r,c);60
}61
}62

63
void count(int v ,int l,int r)64


{65
if(Segtree[v].color !=mixcolor ) 66

{67
colortable[Segtree[v].color]=true;68
return ;69
} 70
int mid=(Segtree[v].left + Segtree[v].right) >> 1;71
if(r<=mid) count(2*v,l,r);72
else if(mid<l) count(2*v+1,l,r);73
else 74

{75
count(2*v,l,mid);76
count(2*v+1,mid+1,r);77
}78
}79

80
int cmp(const void *a,const void *b)81


{82
return ((structx*)a)->v - ((structx*)b)->v;83
}84

85
int main()86


{87
int c,n,i,j,cnt,index; 88
scanf("%d",&c);89
while(c--)90

{91
scanf("%d",&n);92

93
for(i=0,j=0,index=1;i<n;i++)94

{95
scanf("%d%d",&post[i][0],&post[i][1]);96
hash[j].v=post[i][0];hash[j++].line=-index;97
hash[j].v=post[i][1];hash[j++].line=index++;98
}99
//j==2*n100
//離散化101
qsort(hash,j,sizeof(hash[0]),cmp); 102
post[-hash[0].line-1][0]=1;103
for(i=1,index=1;i<j;i++)104

{105
if(hash[i].v!=hash[i-1].v) index++;106

107
if(hash[i].line<0)108
post[-hash[i].line-1][0]=index;109
else post[hash[i].line-1][1]=index;110

111
}112
113
buildsegtree(1,1,index);114
for(i=0;i<n;i++)115
insertseg(1,post[i][0],post[i][1],i+1);116

117
count(1,1,index);118
cnt=0;119
for(i=1;i<=MAXN;i++)120
if(colortable[i]==true) 121

{122
cnt++;123
colortable[i]=false;124
}125
126
printf("%d\n",cnt);127

128
}129
return 0;130
}131



