洛谷P3940 分組(並查集)(暴力)

2021-09-26 23:57:30 字數 1616 閱讀 7716

首先發現資料限制了只有k=1

k=1k=

1和k=

2k=2

k=2的情況,而且值域不是很大,或許可以暴力列舉平方根。

考慮k =1

k=1k=

1的情況,顯然直接列舉平方根,把不能同組出現的數標記一下就行了。

注意我們需要最小化分界的字典序,所以實際上是將字尾劃分得盡量長而已,倒著列舉即可。

考慮k =2

k=2k=

2的情況,仍然考慮列舉平方根,仍然考慮倒序列舉。

現在問題成了怎麼驗證。首先有乙個非常自然的思路,如果把所有有衝突的元素連邊之後是乙個二分圖的話,就合法。

顯然我們並不能直接跑二分圖。我們對於每個點u

uu建立反點v

vv。所有不能和u

uu同色的點必須和v

vv同色,並查集xjb維護一下就行了。

注意一種特殊情況。兩個數的和是乙個完全平方數,顯然我們只需要令它們不在同一集合即可,記錄一下出現次數就行了。

**實現注意細節

**:

#include

#define ll long long

#define re register

#define gc get_char

#define cs const

namespace io

template

<

typename t>

inline t get()

inline

intgi()

}using

namespace io;

using std::cerr;

using std::cout;

cs int n=

3e5+

7,m=

512;

int n,k,mx,last;

int a[n]

,vis[n]

,tag[n]

,fa[n]

;int ans[n]

,cnt;

inline

intgf

(int u)

inline

void

solve1()

}if(flag)

vis[a[i]]=

true;}

}inline

void

solve2()

for(

int re j=

ceil

(sqrt

(a[i]))

;j<=m;

++j)}}

}else

int x1=

gf(a[i]

),x2=

gf(a[i]

+mx)

,y1=

gf(j*j-a[i]

),y2=

gf(j*j-a[i]

+mx);if

(x1==y1)

else}}

} finish:

if(flag)

last=i;

} vis[a[i]]++

;}}signed

main()

洛谷P3940 分組

好題 細節題 答案字典序要求最小,所以考慮倒敘列舉,對於當前一組需要盡量多的加東西,因為後面組選的數越多,前面的選擇機會越多 化列舉序列為列舉值域,這是這道題的關鍵 k 1 倒敘列舉到 i 此時只需判斷當前組中的數是否有加 a i 等於完全平方數的 可以 o n 列舉,但顯然可以更優 列舉所有的完全...

洛谷 P4447分組

大致想法是用乙個佇列記錄當前正在進行中分組的起始位置,並記錄當前分組數,若掃瞄到的下乙個數的個數少於當前分組數,則代表當前有一定數量的分組需要就此停止,按照開始順序依次出佇列即可 include include include include include include include incl...

洛谷p1525 並查集

先將最大的犯罪都找出來然後將人員分組 假設兩人x,y 如果x 前面已經有過敵人了 那就將y合併到x的敵人裡去 y也是如此若有 將x合併到y的敵人去 如果x 和 y前面都沒有 那麼互相將彼此設為敵人 直到找到矛盾的 就是 xy有同乙個敵人 include include include using n...