QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#357810 | #6559. A Tree and Two Edges | ec1117 | WA | 2ms | 6824kb | C++14 | 5.0kb | 2024-03-19 12:53:41 | 2024-03-19 12:53:42 |
Judging History
answer
#include <bits/stdc++.h>
#include <random>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pi;
typedef vector<int> vi;
typedef vector<pi> vpi;
#define mp make_pair
#define f first
#define s second
#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rsz resize
#define bk back()
#define pb push_back
#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define For(i,a) FOR(i,0,a)
#define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i,a) ROF(i,0,a)
#define trav(a,x) for (auto& a: x)
const int MOD = 1e9+7;
const ld PI = acos((ld)-1);
mt19937 rng; // or mt19937_64
template<class T> bool ckmin(T& a, const T& b) {
return b < a ? a = b, 1 : 0; }
void DBG() { cerr << "]" << endl; }
template<class H, class... T> void DBG(H h, T... t) {
cerr << h; if (sizeof...(t)) cerr << ", ";
DBG(t...); }
#ifdef LOCAL // compile with -DLOCAL
#define dbg(...) cerr << "LINE(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
#else
#define dbg(...) 0
#endif
/**
* Description: Disjoint Set Union with path compression
* and union by size. Add edges and test connectivity.
* Use for Kruskal's or Boruvka's minimum spanning tree.
* Time: O(\alpha(N))
* Source: CSAcademy, KACTL
* Verification: USACO superbull
*/
struct DSU {
vi e; void init(int n) { e = vi(n,-1); }
int get(int x) { return e[x] < 0 ? x : e[x] = get(e[x]); }
bool sameSet(int a, int b) { return get(a) == get(b); }
int size(int x) { return -e[get(x)]; }
bool unite(int x, int y) { // union by size
x = get(x), y = get(y); if (x == y) return 0;
if (e[x] > e[y]) swap(x,y);
e[x] += e[y]; e[y] = x; return 1;
}
};
/**template<class T> T kruskal(int n, vector<pair<T,pi>> ed) {
sort(all(ed));
T ans = 0; DSU D; D.init(n+1); // edges that unite are in MST
trav(a,ed) if (D.unite(a.s.f,a.s.s)) ans += a.f;
return ans;
}*/
/**
* Description: Calculates least common ancestor in tree
* with root $R$ using binary jumping.
* Time: O(N\log N) build, O(\log N) query
* Memory: O(N\log N)
* Source: USACO Camp
* Verification: Debug the Bugs
*/
template<int SZ> struct LCA {
static const int BITS = 32-__builtin_clz(SZ);
int N, R = 1, par[BITS][SZ], depth[SZ]; vi adj[SZ];
/// INITIALIZE
void ae(int u, int v) { adj[u].pb(v), adj[v].pb(u); }
void dfs(int u, int prv){
depth[u] = depth[par[0][u] = prv]+1;
trav(v,adj[u]) if (v != prv) dfs(v,u); }
void init(int _N) {
N = _N; dfs(R,0);
FOR(k,1,BITS) FOR(i,1,N+1)
par[k][i] = par[k-1][par[k-1][i]];
}
/// QUERY
int getPar(int a, int b) {
R0F(k,BITS) if (b&(1<<k)) a = par[k][a];
return a; }
int lca(int u, int v){
if (depth[u] < depth[v]) swap(u,v);
u = getPar(u,depth[u]-depth[v]);
R0F(k,BITS) if (par[k][u] != par[k][v])
u = par[k][u], v = par[k][v];
return u == v ? u : par[0][u];
}
int dist(int u, int v) { // # edges on path
return depth[u]+depth[v]-2*depth[lca(u,v)]; }
};
const int SZ = 1<<17;
DSU dsu;
LCA<SZ> lca;
vpi edg;
bool ins(int A, int B, int C) {
int L = lca.lca(A,B);
if(lca.lca(C,L)==L && (lca.lca(C,A)==C || lca.lca(C,B)==C)) {
return true;
}
return false;
}
bool intersect(int A, int B, int C, int D) {
int L = lca.lca(C,D);
// dbg(A,B,C,D,L);
// dbg("B",ins(A,B,C), ins(A,B,D), ins(A,B,L));
if (ins(A,B,C) || ins(A,B,D) || ins(A,B,L)) {
return true;
}
return false;
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(0);
int n,q;cin>>n>>q;
dsu.init(n+1);
For(i,n+1) {
int u,v;cin>>u>>v;
if(!dsu.unite(u,v)) {
dbg(u,v);
edg.pb({u,v});
} else {
lca.ae(u,v);
}
}
dbg("C");
lca.init(n);
dbg("D", edg.size());
assert(edg.size() == 2);
For(i,q) {
int A,B;cin>>A>>B;
int ans = 1;
For(k,2) {
int C = edg[k].f;
int D = edg[k].s;
if(!intersect(A,C,B,D) || !intersect(A,D,C,B)) {
//
dbg(A,B,C,D);
ans++;
}
}
For(j,2) {
For(k,2)For(l,2) {
pi t1 = edg[0];
pi t2 = edg[1];
if(k)
swap(t1.f,t1.s);
if(l)
swap(t2.f,t2.s);
vpi vv = {t1,t2};
if(j)
swap(vv[0],vv[1]);
bool bb = !intersect(A,vv[0].f, vv[0].s, vv[1].f) && !intersect(vv[0].s,vv[1].f,vv[1].s,B) && !intersect(A,vv[0].f,vv[1].s,B);
if(bb){
dbg("Big boy");
ans++;
goto done;
}
}
}
done:;
// int C = edg[0].f, D = edg[0].s;
// int E = edg[1].f, F = edg[1].s;
// bool b1 = !intersect(A,C,D,E) && !intersect(D,E,F,B) && !intersect(A,C,F,B);
// bool b1 = !intersect(A,C,D,F) && !intersect(D,F,E,B) && !intersect(A,C,E,B);
// bool b1 = !intersect(A,D,C,E) && !intersect(C,E,F,B) && !intersect(A,D,F,B);
// bool b1 = !intersect(A,D,C,F) && !intersect(C,F,E,B) && !intersect(A,D,E,B);
cout << "ANS: " << ans << '\n';
}
}
/* stuff you should look for
* int overflow, array bounds
* special cases (n=1?)
* do smth instead of nothing and stay organized
* WRITE STUFF DOWN
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 2ms
memory: 6824kb
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:
ANS: 3 ANS: 3 ANS: 3 ANS: 3 ANS: 3 ANS: 4
result:
wrong answer 1st lines differ - expected: '3', found: 'ANS: 3'