2019 03 02測試T3 層流

2021-09-11 18:22:41 字數 4141 閱讀 8140

傳送門

題目描述:

對於乙個全集 u

uu,對於他的兩個子集 a,b

a,ba,

b,如果 a⊂b

a\subset b

a⊂b 或 b⊂a

b⊂ab⊂

a 或 a∩b

=∅

a∩b=\varnothing

a∩b=

∅,則這兩個集合就是 u

uu 的層流集。

現在小 z 想把這個問題搬到樹上來。他給出 n

nn 個頂點的無根樹,然後他把兩個頂點

v>

v>

的簡單路徑所有的頂點加入乙個集合,這樣就會得到若干個集合。顯然所有頂點構成的集合就是全集 u

uu。他想知道他隨手寫出的若干組

v>

v>

構成的若干子集是否滿足任意兩個集合是 u

uu 的層流集。

輸入格式:

第一行是兩個整數 n,m

n,mn,

m 表示有 n

nn 個頂點,m

mm 組子集。

接下來是 n−1

n-1n−

1 行,每行 2

22 個整數 u,v

u,vu,

v,表示 u

uu ~ v

vv 有一條邊(保證是一顆樹)。

接下來 m

mm 行,每行兩個整數 u,v

u,vu,

v 表示由 u

uu 到 v

vv 的簡單路徑上頂點構成乙個子集。

輸出格式:

如果給出的 m

mm 個子集任意兩個子集滿足是全集的層流集輸出 「yes」 否則輸出 「no」。

樣例資料:輸入

4 21 2

2 32 4

1 24 2 輸出

no 子任務一(5

55 分):n,m

≤15

n,m\le15

n,m≤15

;子任務二(25

2525

分):n,m

≤1000

n,m\le1000

n,m≤10

00;子任務三(70

7070

分):n,m

≤100000

n,m\le100000

n,m≤10

0000

。先考慮怎麼判斷兩個集合 a,b

a,ba,

b 是否是 u

uu 的層流集。

如果存在兩個集合 a,b

a,ba,

b ,使得 a,b

a,ba,

b 有交叉(此處的交叉定義為 a,b

a,ba,

b 有交集但是不存在包含關係),那就不滿足任意兩個集合都是 u

uu 的層流集(也就是輸出 「no」),如果不存在這樣的一對集合,就輸出 「yes」。

我們將路徑的長度從大到小排序,然後從大到小加邊,每次判斷之前的邊與這條邊是否有交叉。

怎麼判斷是否有交叉呢,不妨在每次加入一條邊之後,對這條邊上的點染上乙個新顏色。判斷交叉的時候,就看這條邊上有幾種顏色,如果有多於 1

11 種的顏色,就說明這條邊與之前的邊有交叉。

然後怎麼判斷是否只有 1

11 種顏色呢,可以記錄下路徑上的最大最小值,判斷最大最小值是否相等即可。

可以自己畫一下圖來理解。

然後具體的實現可以看**(雖然**量巨大)。

#include

#include

#include

#define n 100005

using

namespace std;

int n,m,t,tot;

struct edgee[n]

;int first[n]

,v[n<<1]

,nxt[n<<1]

;int max[n<<2]

,min[n<<2]

,cov[n<<2]

;int fa[n]

,son[n]

,dep[n]

,size[n]

,pos[n]

,top[n]

;bool

operator

<

(const edge &p,

const edge &q)

void

add(

int x,

int y)

void

dfs1

(int x)

}void

dfs2

(int x,

int tp)

intlca

(int x,

int y)

return

(dep[x]

)?x:y;

}void

pushup

(int root)

void

pushnow

(int root,

int k)

void

pushdown

(int root,

int l,

int r,

int mid)

intquerymax

(int root,

int l,

int r,

int x,

int y)

intfindmax

(int x,

int y)

if(dep[x]

>dep[y]

)swap

(x,y)

; ans=

max(ans,

querymax(1

,1,n,pos[x]

,pos[y]))

;return ans;

}int

querymin

(int root,

int l,

int r,

int x,

int y)

intfindmin

(int x,

int y)

if(dep[x]

>dep[y]

)swap

(x,y)

; ans=

min(ans,

querymin(1

,1,n,pos[x]

,pos[y]))

;return ans;

}void

cover

(int root,

int l,

int r,

int x,

int y,

int k)

int mid=

(l+r)

>>1;

if(x<=mid)

cover

(root<<

1,l,mid,x,y,k);if

(y>mid)

cover

(root<<1|

1,mid+

1,r,x,y,k)

;pushup

(root);}

void

modify

(int x,

int y,

int k)

if(dep[x]

>dep[y]

)swap

(x,y)

;cover(1

,1,n,pos[x]

,pos[y]

,k);

}int

main()

dfs1(1

),dfs2(1

,1);

for(i=

1;i<=m;

++i)

sort

(e+1

,e+m+1)

;for

(i=1

;i<=m;

++i)

modify

(e[i]

.u,e[i]

.v,i);}

puts

("yes");

return0;

}

2018 11 05測試T3 相交

傳送門 一道不錯的題 首先,要知道乙個東西,即若兩條路徑相交,則一條路徑的 lca lcalc a 必然在另一條路徑上 我們每加入一條邊,都計算一下之前的邊加上它對答案的貢獻 現在假設加 a,b a,b a,b 條邊,具體有一下幾種情況 統計 a,b a,b a,b 這條路徑上的 lca lcalc...

2019 03 30測試T3 里程表

傳送門 題目描述 農民約翰的牛正開始乙個美妙的旅程。牛車的里程表上顯示乙個整數表示里程,旅程開始時里程數為 x 100 x 1018 x 100 le x le 10 x 100 x 10 18 結束時里程數為 y x y 1 018 y x le y le 10 y x y 1018 每當里程表顯...

T3進銷存公升級T 備忘

t3進銷存資料公升級t 只能公升級各種基礎檔案和截至某月底的結存數量 不含單價 金額 一 安裝及加密識別 1.1 因為不能公升級歷史業務單據,所以如果要查詢t3的歷史資料,需要在訂購t 時同時訂購t3查詢工具。1.2 t3和t 需要安裝在一台電腦,t3主要查詢,不再做新資料,所以想用高版本sql,也...