1. 程式人生 > >我對離散化的一些感悟

我對離散化的一些感悟

這幾天在做線段樹的專題,不免遇到一些題,資料很大,如果直接建樹,會造成記憶體超出限制,這時就要進行離散化了。如果是區間的離散化,一般區間會涉及覆蓋關係, 那麼運用離散化之後,區間的覆蓋關係不能變,例如:1——10 ,2——7 ,3——11,6——22;將座標從小到大排序,也就是1,2,3,6,7,10,11,22那麼新的區間也就是1——62——53——74——8覆蓋關係沒變,但是值小了很多,瞬間就減少了記憶體消耗

int seg[maxn][2];//儲存原來的點

struct node
{
int p;
int line;
}mat[maxn<<1]

for(.....)
{
scanf(".....");
mat[i<<1].line=-(i+1);
mat[i<<1|1].line=(i+1);
mat[i<<1].p=seg[i][0];
mat[i<<1|1].p=seg[i][1];
}

sort(mat,mat+2*n,cmp);
for(.....)
{
if(temp!=seg[i].p)//防止相同端點對映到不同的點,temp是上一個點
{
ans++;
temp=seg[i].p;
}
if(mat[i].line<0) //左邊,line 存的就是第i+1條邊
seg[-mat[i].line-1][0]=ans;//離散這條邊的左端
else
seg[mat[i].line-1][1]=ans;//離散這條邊的右端
}

這樣的話,離散前的點是沒了,如果我們不需要離散前的點,那麼可以這麼做,如果需要的話,可以開陣列儲存下來或者用map,把離散前的座標當成key,離散化的做value。這樣即離散了座標,也保留了原座標離散化適用於處於資料極大時的情況,例如應用線上段樹上。