COGS 2479 偏序 題解

2022-02-27 14:24:10 字數 3086 閱讀 1549

【題意】

給定乙個有n個元素的序列,元素編號為1~n,每個元素有三個屬性a,b,c,求序列中滿足ii

j且bi

j且ci

j的數對(i,j)的個數。

對於30%的資料,n<=5000。

對於100%的資料,1<=n<=50000(原題寫錯了哈哈),保證所有的ai、bi、ci分別組成三個1~n的排列。

【解法】

標題已經說了這是偏序,讀完題,這就是個四維偏序模板題(位置一維,a,b,c剩下三維)。

解法多多,我用的是cdq樹套樹(樹套樹寫的樹狀陣列套替罪羊樹,畢竟在我的印象裡替罪羊樹在隨機資料下跑得飛快)。

第一維已經有序,不用我們預處理,這樣就可以按第一維(位置)分治,再把第二維(a)排序,剩下的第三維(b)和第四維(c)直接樹套樹就可以了(我用的是第三維樹狀陣列,第四維平衡樹)。

當然寫cdq套cdq+樹狀陣列應該也可以,然而本鶸渣不會寫……

也可以寫樹套樹套樹……然而怎麼寫……

貼個**:

1 #include2 #include3 #include4

#define siz(x) ((x)?((x)->size):(0))

5#define lowbit(x) ((x)&(-(x)))

6using

namespace

std;

7const

int maxn=50010;8

const

double a=0.65;9

struct node

13 inline void refresh()

14 }*root[maxn];

15structb18

}a[maxn],b[maxn];

19void cdq(int,int

);20

void add(int,int

);21

void del(int,int

);22

int query(int,int

);23

void insert(int

);24

void erase(int

);25

int rank(int

);26 node *insert(node*);

27 node *find(int

);28 node *erase(node*);

29 node *findmax(node*);

30void rebuild(node*);

31void zorder(node*);

32void removetree(node*);

33 node *rebuild(int,int

);34

intn,t,cnt,data[maxn];

35long

long ans=0ll;

36int

main()

55void cdq(int l,int

r)65

while(i<=mid)b[k++]=a[i++];

66while(j<=r)b[k++]=a[j++];

67for(int i=l;i<=r;i++)

72for(int i=l;i<=r;i++)if(a[i].id<=mid)del(a[i].b,a[i].c);73}

74void add(int x,int

d)80}81

void del(int x,int

d)87}88

int query(int x,int

d)95

return

ans;96}

97void insert(int

x)101

void erase(int

x)105

int rank(int

x)114

}115

return

ans;

116}

117 node *insert(node *x)

122 node *rt=root[t];

123for

(;;)

130}

131else

137}

138}

139 x->prt=rt;

140 x=null;

141for(;rt;rt=rt->prt)

145return

x;146

}147 node *find(int

x)154

return

null;

155}

156 node *erase(node *x)

162if(!x->lc&&!x->rc)

167else root[t]=null;

168}

169else

if(x->lc&&!x->rc)

175else root[t]=x->lc;

176}

177else

if(!x->lc&&x->rc)

183else root[t]=x->rc;

184}

185 node *rt=x->prt;

186delete

x;187 x=null;

188for(;rt;rt=rt->prt)

192return

x;193

}194 node *findmax(node *x)

198void rebuild(node *rt)

207else root[t]=x;

208removetree(rt);

209}

210void removetree(node *x)

216void zorder(node *x)

222 node *rebuild(int l,int

r)

view code

【後記】

這個題是用cdq+樹狀陣列水掉三維偏序之後的腦洞的產物……貌似在報復社會……

自己真是玩瘋了……

cogs247 售票系統

某次列車途經c個城市,城市編號依次為1到c,列車上共有s個座位,鐵路局規定售出的車票只能是坐票,即車上所有的旅客都有座。售票系統是由計算機執行的,每乙個售票申請包含三個引數,分別用o d n表示,o為起始站,d為目的地站,n為車票張數。售票 系統對該售票申請作出受理或不受理的決定,只有在從o到d的區...

cogs247 售票系統 線段樹

某次列車途經c個城市,城市編號依次為1到c,列車上共有s個座位,鐵路局規定售出的車票只能是坐票,即車上所有的旅客都有座。售票系統是由計算機執行的,每乙個售票申請包含三個引數,分別用o d n表示,o為起始站,d為目的地站,n為車票張數。售票 系統對該售票申請作出受理或不受理的決定,只有在從o到d的區...

cogs247 售票系統 線段樹

輸入檔案 railway.in 輸出檔案 railway.out 時間限制 1 s 記憶體限制 128 mb 問題描述 某次列車途經c個城市,城市編號依次為1到c,列車上共有s個座位,鐵路局規定售出的車票只能是坐票,即車上所有的旅客都有座。售票系統是由計算機執行的,每乙個售票申請包含三個引數,分別用...