1. 程式人生 > >BZOJ2054 瘋狂的饅頭 又叕是並查集!

BZOJ2054 瘋狂的饅頭 又叕是並查集!

def www. mes 第一個 壓縮 clas tdi 暴力 代碼

BZOJ2054 瘋狂的饅頭 又叕是並查集!

瘋狂的饅頭 滴傳送門

以下是做此題的感想


搜並查集的題搜到了這題
看到這題 yi 好熟悉 可是不會...
不是暴力嗎
哇這個n和m
對不起打擾了..
模擬了一下樣例
感覺前面的有點染色都會被後面的覆蓋掉
所以可能只要後面一部分就好了?
可是怎麽知道從哪邊開始染...
要不倒著染?
每次只染白色的?
那不還是O(nm)...
誒這題應該是並查集啊
還沒用過並查集呢..
fa[x]記錄x及x以後的第一個白色的點吧!
那可以通過fa[]每次在x到y的區間裏找白色的染就好了吧
誒這樣的話好像真的不會超時誒
好神奇好妙妙
我愛並查集!


然後我就開心地交了

TLE...
???
不會吧
看看代碼 我都用register了
難不成還卡常?
於是看到了沒有用路徑壓縮的赤裸裸的find..
改完之後
RE???
為啥??
於是看到了初始化fa[]的時候1~n
忘記初始化n+1了TAT

---

Code

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#define ll long long
using namespace std;

int n, m, p, q, a[1000007], fa[1000007];
inline int read(){
    int ans = 0, f = 1;
    char ch = getchar();
    for(; ch < '0' || ch > '9'; ch = getchar())
        if (ch == '-')
            f = 0;
    for(; ch >= '0' && ch <= '9'; ch = getchar())
        ans = (ans << 3) + (ans << 1) + ch - 48;
    return f? ans: -ans;
}
int find(int x){
    return fa[x] == x ? x : fa[x] = find(fa[x]);
}
int main(){
    n = read(), m = read(), p = read(), q =read();
    for (register int i = 1; i <= n + 1; ++i)
        fa[i] = i;
    for (register int i = m; i >= 1; i--){
        int x = (i * p + q) % n + 1, y = (i * q + p) % n + 1;
        if (x > y)
            swap(x, y);
        for (int j = find(x); j <= y; j = find(j))
            a[j] = i, fa[j] = j + 1;
    }
    for (register int i = 1; i <= n; ++i)
        printf("%d\n", a[i]);
    return 0;
}

BZOJ2054 瘋狂的饅頭 又叕是並查集!