求密梅, 急

T1 什么 j

正解和数据最多存在一个, 我卡了两个小时终于用正解以暴力的 100 倍的时间过了这 j 题

另外这正解的复杂度一点也不正解, 其实本来不应该这么着急

但是完全遍历的暴力不能拿最优解吧

正解拿暴力分, 暴力拿正解分 ——\(\color{black}s\color{red}{andom}\)

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("O2")
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize(La_Pluma)
#include <map>
#include <vector>
#include <bitset>
#include <iostream>
const int maxn = 3e4 + 4;
std::pair<int, int> Ask[maxn * 10], edge[maxn * 10];
std::map<std::pair<int, int>, int> ans;
std::bitset<maxn> ash[maxn], ask[maxn];
int n, m, mx, T, u, v, w, fa[maxn], vis[maxn];
int sta[maxn], top;
int find(int x){return fa[x] == x ? x : fa[x] = find(fa[x]);}
int main(){
    freopen("gcd.in", "r", stdin);
    freopen("gcd.out", "w", stdout);
    scanf("%d%d%d", &n, &m, &T);
    for(int i = 1; i <= m; ++i){
        scanf("%d%d%d", &u, &v, &w);
        edge[w] = {u, v};
        if(w > mx) mx = w;
    }
    for(int i = 1; i <= T; ++i) scanf("%d%d", &u, &v), ask[u][v] = 1, Ask[i] = {u, v};
    for(int i = 1; i <= n; ++i) fa[i] = i;
    for(int i = mx; i; --i){
        for(int j = i; j <= mx; j += i) if(edge[j].first) {
            u = find(edge[j].first), v = find(edge[j].second);
            if(!vis[u]) sta[++top] = u, vis[u] = 1;
            if(!vis[v]) sta[++top] = v, vis[v] = 1;
            ash[u][edge[j].first] = 1;
            ash[u][edge[j].second] = 1;
            ash[u] |= ash[v];
            fa[v] = u;
        }
        for(int __La_Pluma__ = 1; __La_Pluma__ <= top; ++__La_Pluma__) if(ask[sta[__La_Pluma__]].any()) {
            int j = sta[__La_Pluma__];
            auto t = ash[find(j)] & ask[j];
            for(int k = t._Find_first(); k != t.size(); k = t._Find_next(k)) ans[{j, k}] = i;
            ask[j] ^= t;
        }
        while(top) ash[sta[top]].reset(), fa[sta[top]] = sta[top], vis[sta[top]] = 0, --top;
    }
    for(int i = 1; i <= T; ++i) printf("%d\n", ans[Ask[i]] ? ans[Ask[i]] : -1);
    return 0;
}

posted @ 2022-11-22 16:39  La_pluma  阅读(40)  评论(2编辑  收藏  举报