QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#357811 | #6559. A Tree and Two Edges | ec1117 | WA | 188ms | 17472kb | C++14 | 5.0kb | 2024-03-19 12:54:00 | 2024-03-19 12:54:01 |
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 << '\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
*/
详细
Test #1:
score: 100
Accepted
time: 3ms
memory: 15492kb
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:
3 3 3 3 3 4
result:
ok 6 lines
Test #2:
score: 0
Accepted
time: 0ms
memory: 14736kb
input:
6 4 1 2 1 3 1 6 2 3 3 4 3 5 4 5 1 2 1 3 1 4 1 6
output:
2 2 4 1
result:
ok 4 lines
Test #3:
score: -100
Wrong Answer
time: 188ms
memory: 17472kb
input:
50000 50000 11561 23122 14261 28523 24407 48814 17947 35894 14803 29607 19557 39115 12415 24830 9583 19167 18397 36794 439 878 18040 36080 17150 34300 7922 15845 18938 37877 18625 37250 6459 12919 9818 19636 3579 7158 21323 42646 23882 47764 13603 27207 8353 16707 15907 31814 20935 41871 11686 23372...
output:
4 4 3 4 4 4 3 4 4 4 3 4 4 4 4 4 4 3 4 4 4 4 4 3 4 4 4 4 4 4 3 4 3 3 4 4 4 4 4 4 4 4 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 3 4 4 4 4 4 4 4 4 3 4 3 4 4 4 4 4 3 4 4 4 4 4 4 4 4 4 4 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 3 4 4 4 4 4 4 4 4 4 3 4 4 4 4 4 4 3 4 4 4 4 4 4 4 3 3 4 4 4 4 3 3 4 4 4 4 4 3 4 4 4 3 4 4 4 3 4 4 4 ...
result:
wrong answer 2nd lines differ - expected: '3', found: '4'