QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#357811#6559. A Tree and Two Edgesec1117WA 188ms17472kbC++145.0kb2024-03-19 12:54:002024-03-19 12:54:01

Judging History

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

  • [2024-03-19 12:54:01]
  • 评测
  • 测评结果:WA
  • 用时:188ms
  • 内存:17472kb
  • [2024-03-19 12:54:00]
  • 提交

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
*/

Details

Tip: Click on the bar to expand more detailed information

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'