IOI2018 排座位 線段樹

2022-05-08 03:24:11 字數 2450 閱讀 3216

ioi2018seat

這題思路真的很神。

原題編號從0開始,很不舒服,我們按從1開始的講。

發現只需要判斷[1,i]這些數是否組成了乙個矩陣。

那麼我們能不能用線段樹,第i個葉子節點存前i個數的資訊來判斷前i個數能否組成矩陣呢?

有的人可能會想到第i個葉子節點維護前i個數中最左上的點和最右下的點,判斷時直接取這兩個點形成矩形的面積看是否等於i。

這個判斷是可行了,但修改呢?你會發現交換兩個點的位置會改變好多點的資訊,甚至影響的資訊達到o(n)級別。

這時真正的神仙操作來了。

在判斷前i個點是否成立時我們將前i個點染成黑色,其他點為白色。

我們維護兩個資訊:

1、有多少黑點的左邊和上邊都是白點或邊界

2、有多少白點的四聯通塊中包含大於等於2個黑點

可以看出,如果前i個點形成矩形那麼第乙個資訊值為1,第二個資訊值為0。同理也只有這種情況才是矩形。

為什麼呢?

如果黑點都連在一起形成乙個圖形,那麼第二個資訊為0保證他是乙個凸多邊形且多邊形的邊與整個圖是平行的,

而第乙個資訊為1則保證他有四個頂點。

如果還是不太明白可以手畫一下。

不管所有黑點組成什麼圖形都至少有乙個左上頂點,因此第乙個資訊的值一定是正數。

我們維護兩個資訊不方便,不妨維護他們兩個的和,那麼就只有和為1時是成立的。

那麼怎麼修改?

對於第i個點我們求出它作為白點有貢獻的開始時刻l(即它的四聯通塊中編號第二小的)和作為黑點有貢獻的結束時刻r(即它左邊和上邊兩個點中編號最小的)。

那麼這個點作為白點時會對[l,i-1]這段時刻有貢獻,而作為黑點是會對[i,r-1]這段時刻有貢獻。

交換兩個點會影響這兩個點的四聯通塊最多10個點的l和r,先減去原先每個點的貢獻,交換位置後再對每個點有貢獻的時間段區間修改即可,注意這些修改的點要去重。

#include"seats.h"

#include#include#include#include#include#define ll long long

#define mp(x,y) (b[(x-1)*m+y])

#define sx(i) (a[i].x)

#define sy(i) (a[i].y)

#define fx(x,i) (x+dx[i])

#define fy(x,i) (x+dy[i])

#define check(x,y) (x>=1&&x<=n&&y>=1&&y<=m)

using namespace std;

int dx[4]=;

int dy[4]=;

int b[1000010];

int mn[4000010];

int sum[4000010];

int t[4000010];

int v[1000010];

int n,m,q;

int x,y;

int st[15];

int top;

struct miku

a[1000010];

inline void pushup(int rt)

if(mn[rt<<1|1]==mn[rt]) }

inline void pushdown(int rt)

}inline void build(int rt,int l,int r)

int mid=(l+r)>>1;

build(rt<<1,l,mid);

build(rt<<1|1,mid+1,r);

pushup(rt);

}inline void change(int rt,int l,int r,int l,int r,int k)

pushdown(rt);

int mid=(l+r)>>1;

if(l<=mid)

if(r>mid)

pushup(rt);

}inline int begin_white(int x)

top=0;

st[++top]=x;

st[++top]=y;

for(int i=0;i<4;i++) }

for(int i=0;i<4;i++) }

sort(st+1,st+1+top);

for(int i=1;i<=top;i++)

}} swap(mp(sx(x),sy(x)),mp(sx(y),sy(y)));

swap(a[x],a[y]);

for(int i=1;i<=top;i++)

}} return sum[1];

}void give_initial_chart(int h, int w,vectorr,vectorc)

for(int i=1;i<=n*m;i++)

for(int j=0;j<4;j++)

}} }

build(1,1,n*m);

}

5 2 排座位 25分

5 2 排座位 25分 布置宴席最微妙的事情,就是給前來參宴的各位賓客安排座位。無論如何,總不能把兩個死對頭排到同一張宴會桌旁!這個艱鉅任務現在就交給你,對任何一對客人,請編寫程式告訴主人他們是否能被安排同席。輸入第一行給出3個正整數 n le 100 即前來參宴的賓客總人數,則這些人從1到n編號 ...

7 10 排座位 25分

布置宴席最微妙的事情,就是給前來參宴的各位賓客安排座位。無論如何,總不能把兩個死對頭排到同一張宴會桌旁!這個艱鉅任務現在就交給你,對任何一對客人,請編寫程式告訴主人他們是否能被安排同席。輸入第一行給出3個正整數 n 100 即前來參宴的賓客總人數,則這些人從1到n編號 m為已知兩兩賓客之間的關係數 ...

CCCC 天梯賽 5 10 排座位

5 10 排座位 25分 布置宴席最微妙的事情,就是給前來參宴的各位賓客安排座位。無論如何,總不能把兩個死對頭排到同一張宴會桌旁!這個艱鉅任務現在就交給你,對任何一對客人,請編寫程式告訴主人他們是否能被安排同席。輸入第一行給出3個正整數 n le 100 即前來參宴的賓客總人數,則這些人從1到n編號...