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編號...