QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#351537#6559. A Tree and Two EdgesjanYWA 0ms3848kbC++206.3kb2024-03-12 01:09:072024-03-12 01:09:07

Judging History

你现在查看的是最新测评结果

  • [2024-03-12 01:09:07]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:3848kb
  • [2024-03-12 01:09:07]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,popcnt,lzcnt")
#define fo(i,n) for(i=0;i<n;i++)
#define Fo(i,k,n) for(i=k;k<n?i<n:i>n;k<n?i+=1:i-=1)
#define ll long long
#define ld long double
#define ull unsigned long long
#define all(x) x.begin(), x.end()
#define sortall(x) sort(all(x))
#define rev(x) reverse(x.begin(), x.end())
#define fi first
#define se second
#define pb push_back
#define PI 3.14159265359
typedef pair<int, int>	pii;
typedef pair<ll, ll>	pl;
typedef vector<int>		vi;
typedef vector<ll>		vl;
typedef vector<pii>		vpii;
typedef vector<pl>		vpl;
typedef vector<vi>		vvi;
typedef vector<vl>		vvl;
bool sortbysec(const pair<int,int> &a,const pair<int,int> &b){return (a.second < b.second);}
#define sortpairbysec(x) sort(all(x), sortbysec)
bool sortcond(const pair<int,int> &a,const pair<int,int> &b){
    if (a.fi != b.fi){
        return a.fi < b.fi;
    } else {
        return a.se > b.se;
    }
}
struct myComp {
    constexpr bool operator()( pii const& a, pii const& b) const noexcept
    {
        if (a.first != b.first){
            return a.first < b.first;
        } else {
            return a.second > b.second;
        }
    }
};
mt19937_64 rang(chrono::high_resolution_clock::now().time_since_epoch().count());
ll rng(ll lim) {
    uniform_int_distribution<ll> uid(0,lim-1);
    return uid(rang);
}

const int mod = 998244353;
const int N = 3e5, M = N;
const ll inf = 1e18;
//=======================
struct disjSet { // Disjoint set
    int *rank, *parent, n;
    disjSet() {}
	disjSet(int n) {init(n);}
    void init(int n){
        rank = new int[n];
		parent = new int[n];
		this->n = n;
		for (int i = 0; i < n; i++) {
            rank[i] = 0;
            parent[i] = i;
        }
    }
	int find(int a) {
		if (parent[a] != a){
            //return find(parent[a]); // no path compression
            parent[a] = find(parent[a]); // path compression
        }
		return parent[a];
	}
	bool Union(int a, int b) {
		int a_set = find(a);
		int b_set = find(b);
		if (a_set == b_set) return false;
		if (rank[a_set] < rank[b_set]) {
            update_union(a_set, b_set);
		} else if (rank[a_set] > rank[b_set]) {
            update_union(b_set, a_set);
		} else {
            update_union(b_set, a_set);
			rank[a_set] = rank[a_set] + 1;
		}
        return true;
	}
    // change merge behaviour here
    void update_union(int a, int b){ // merge a into b
        parent[a] = b;
    }
};
//=======================
// & - bitwise AND; | - bitwise OR; ^ - bitwise XOR
// cout.precision(7);
// next_permutation(arr.begin(), arr.end());
// long long long long long long long long long long long long long long long long long long long long long long long long long long long
// priority_queue<int, vector<int>, greater<int>> a; (min heap)
// ll hash1 = hash<string>{}(to_string(1));
// always lower_bound
// __builtin_clz(n) count leading zeros

vl a;
ll n, m, k, q;
vector<vector<bool>> ans;
vpii xtra;
vvi g;
vector<pii> is_good;
vector<vpii> que;
vi blocked;

void fill_subtree(int loc, int p, int val, bool stop_block){
    if (blocked[loc]) return;
    is_good[loc] = {val, p};
    for (auto &i : g[loc]){
        if (i == p || (stop_block && blocked[i])) continue;
        fill_subtree(i, loc, val, stop_block);
    }
}

void walk(int loc, int p, int typ){
    if (blocked[loc]) return;
    blocked[loc] = 1;
    pii rem = {-1, -1};
    if (is_good[loc].fi == 1){
        rem = is_good[loc];
        for (auto &i : g[loc]){
            if (i == p || i == rem.se) continue;
            fill_subtree(i, loc, 0, 1);
        }
        is_good[loc] = {0, 0};
    }

    for (auto &i : que[loc]){
        if (is_good[i.fi].fi == 1) ans[typ][i.se] = 1;
    }

    for (auto &i : g[loc]){
        if (i == p) continue;
        walk(i, loc, typ);
    }

    if (rem != (pii){-1, -1}){
        is_good[loc] = rem;
        for (auto &i : g[loc]){
            if (i == p || i == rem.se) continue;
            fill_subtree(i, loc, 1, 1);
        }
    }
    blocked[loc] = 0;
}

bool block_path(int loc, int p, int targ){
    if (loc == targ){
        blocked[loc] = 1;
        return 1;
    }
    for (auto &i : g[loc]){
        if (i == p) continue;
        if (block_path(i, loc, targ)){
            blocked[loc] = 1;
            return 1;
        }
    }
    return 0;
}

void test(int typ){
    blocked.assign(n, 0);
    is_good.assign(n, {0, 0});

    if (typ == 2){
        block_path(xtra[0].se, xtra[0].se, xtra[1].fi);
        blocked[xtra[0].fi] = 1;
        fill_subtree(xtra[0].fi, xtra[0].fi, 1, 1);
        walk(xtra[1].se, xtra[1].se, typ);
        return;
    }
    
    pii the_edge;
    if (typ == 0) the_edge = xtra[0];
    if (typ == 1) the_edge = xtra[1];
    blocked[the_edge.se] = 1;
    fill_subtree(the_edge.se, the_edge.se, 1, 1);
    walk(the_edge.fi, the_edge.fi, typ);
}

void solve(int tc) {
    int i, j;
    cin >> n >> q;
    ans.resize(3, vector<bool>(q, 0));

    disjSet dsu(n);
    g.resize(n);

    fo(i, n+1){
        int u, v;
        cin >> u >> v;
        u--; v--;
        if (dsu.Union(u, v)){
            g[u].pb(v);
            g[v].pb(u);
        } else {
            xtra.pb({u, v});
        }
    }

    que.resize(n);
    fo(i, q){
        int u, v;
        cin >> u >> v;
        u--; v--;
        que[u].pb({v, i});
    }

    test(0);
    swap(xtra[0].fi, xtra[0].se);
    test(0);

    test(1);
    swap(xtra[1].fi, xtra[1].se);
    test(1);

    test(2);
    swap(xtra[0].fi, xtra[0].se);
    test(2);
    swap(xtra[1].fi, xtra[1].se);
    test(2);
    swap(xtra[0].fi, xtra[0].se);
    test(2);

    swap(xtra[0], xtra[1]);

    test(2);
    swap(xtra[0].fi, xtra[0].se);
    test(2);
    swap(xtra[1].fi, xtra[1].se);
    test(2);
    swap(xtra[0].fi, xtra[0].se);
    test(2);

    fo(i, q){
        cout << 1+ans[0][i]+ans[1][i]+ans[2][i] << "\n";
        // cout << ans[0][i] << " " << ans[1][i] << " " << ans[2][i] << "\n";
    }
}
 
int main() {
    ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    srand(chrono::high_resolution_clock::now().time_since_epoch().count());

    int t = 1;
    // cin >> t;
    int i;
    fo(i, t) {
        solve(i+1);
    }
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 0ms
memory: 3848kb

input:

4 6
1 2
1 3
1 4
2 3
2 4
1 2
1 3
1 4
2 3
2 4
3 4

output:

1
1
1
1
1
1

result:

wrong answer 1st lines differ - expected: '3', found: '1'