Submission #547385

#TimeUsernameProblemLanguageResultExecution timeMemory
547385dualityJail (JOI22_jail)C++17
100 / 100
2195 ms199044 KiB
#define DEBUG 0 #include <bits/stdc++.h> using namespace std; #if DEBUG // basic debugging macros int __i__,__j__; #define printLine(l) for(__i__=0;__i__<l;__i__++){cout<<"-";}cout<<endl #define printLine2(l,c) for(__i__=0;__i__<l;__i__++){cout<<c;}cout<<endl #define printVar(n) cout<<#n<<": "<<n<<endl #define printArr(a,l) cout<<#a<<": ";for(__i__=0;__i__<l;__i__++){cout<<a[__i__]<<" ";}cout<<endl #define print2dArr(a,r,c) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<a[__i__][__j__]<<" ";}cout<<endl;} #define print2dArr2(a,r,c,l) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<setw(l)<<setfill(' ')<<a[__i__][__j__]<<" ";}cout<<endl;} // advanced debugging class // debug 1,2,'A',"test"; class _Debug { public: template<typename T> _Debug& operator,(T val) { cout << val << endl; return *this; } }; #define debug _Debug(), #else #define printLine(l) #define printLine2(l,c) #define printVar(n) #define printArr(a,l) #define print2dArr(a,r,c) #define print2dArr2(a,r,c,l) #define debug #endif // define #define MAX_VAL 999999999 #define MAX_VAL_2 999999999999999999LL #define EPS 1e-6 #define mp make_pair #define pb push_back // typedef typedef unsigned int UI; typedef long long int LLI; typedef unsigned long long int ULLI; typedef unsigned short int US; typedef pair<int,int> pii; typedef pair<LLI,LLI> plli; typedef vector<int> vi; typedef vector<LLI> vlli; typedef vector<pii> vpii; typedef vector<plli> vplli; // ---------- END OF TEMPLATE ---------- int S[120000],T[120000]; vi adjList[120000]; vi adjList2[2500000]; int parent[120000][17],depth[120000],disc[120000],fin[120000],num = 0,siz[120000],heavy[120000]; int chain[120000],head[120000],csize[120000],c = 0; int doDFS(int u,int p,int d) { parent[u][0] = p,depth[u] = d,siz[u] = 1,heavy[u] = -1; for (int v: adjList[u]) { if (v != p) { doDFS(v,u,d+1); siz[u] += siz[v]; if ((heavy[u] == -1) || (siz[heavy[u]] < siz[v])) heavy[u] = v; } } return 0; } int doHLD(int u,int p) { chain[u] = c,disc[u] = num++; if (csize[c] == 0) head[c] = u; csize[c]++; if (heavy[u] != -1) doHLD(heavy[u],u); for (int v: adjList[u]) { if ((v != p) && (v != heavy[u])) c++,doHLD(v,u); } fin[u] = num; return 0; } int logn; int lca(int u,int v) { int i; if (depth[u] < depth[v]) swap(u,v); for (i = logn-1; i >= 0; i--) { if ((parent[u][i] != -1) && (depth[parent[u][i]] >= depth[v])) u = parent[u][i]; } if (u == v) return u; for (i = logn-1; i >= 0; i--) { if (parent[u][i] != parent[v][i]) u = parent[u][i],v = parent[v][i]; } return parent[u][0]; } int anc(int u,int v) { return ((disc[v] >= disc[u]) && (disc[v] < fin[u])); } int onPath(int u,int v,int w,int l) { if (!anc(l,w)) return 0; return anc(w,u) || anc(w,v); } vi tree1[1 << 18],tree2[1 << 18]; int node1[1 << 18],node2[1 << 18]; int update(int s,int e,int ai,int i,int u,int t) { if ((s > ai) || (e < ai)) return 0; else if (s == e) { if (t == 1) tree1[i].pb(u); else tree2[i].pb(u); return 0; } int mid = (s+e) / 2; update(s,mid,ai,2*i+1,u,t),update(mid+1,e,ai,2*i+2,u,t); if (t == 1) tree1[i].pb(u); else tree2[i].pb(u); return 0; } int build(int s,int e,int i) { if (s == e) { node1[i] = num++; for (int u: tree1[i]) adjList2[u].pb(node1[i]); node2[i] = num++; for (int u: tree2[i]) adjList2[node2[i]].pb(u); return 0; } int mid = (s+e) / 2; build(s,mid,2*i+1),build(mid+1,e,2*i+2); node1[i] = num++; for (int u: tree1[i]) adjList2[u].pb(node1[i]); node2[i] = num++; for (int u: tree2[i]) adjList2[node2[i]].pb(u); return 0; } int add(int s,int e,int as,int ae,int i,int u,int t) { if ((s > ae) || (e < as)) return 0; else if ((s >= as) && (e <= ae)) { if (t == 1) adjList2[node1[i]].pb(u); else adjList2[u].pb(node2[i]); return 0; } int mid = (s+e) / 2; add(s,mid,as,ae,2*i+1,u,t),add(mid+1,e,as,ae,2*i+2,u,t); return 0; } int clear(int s,int e,int i) { if (s == e) { tree1[i].clear(),tree2[i].clear(); return 0; } int mid = (s+e) / 2; clear(s,mid,2*i+1),clear(mid+1,e,2*i+2); tree1[i].clear(),tree2[i].clear(); return 0; } int visited[2500000],no = 0; int doDFS2(int u) { if (visited[u] != 0) { if (visited[u] == 1) no = 1; return 0; } visited[u] = 1; for (int v: adjList2[u]) doDFS2(v); visited[u] = 2; return 0; } int main() { int i,j; int Q,N,M,A,B; scanf("%d",&Q); while (Q--) { scanf("%d",&N); for (i = 0; i < N-1; i++) { scanf("%d %d",&A,&B); A--,B--; adjList[A].pb(B); adjList[B].pb(A); } scanf("%d",&M); for (i = 0; i < M; i++) scanf("%d %d",&S[i],&T[i]),S[i]--,T[i]--; num = 0,doDFS(0,-1,0); doHLD(0,-1),c++; for (i = 1; (1 << i) < N; i++) { for (j = 0; j < N; j++) { if (parent[j][i-1] != -1) parent[j][i] = parent[parent[j][i-1]][i-1]; else parent[j][i] = -1; } } logn = i; num = M; for (i = 0; i < M; i++) { update(0,N-1,disc[S[i]],0,i,1); update(0,N-1,disc[T[i]],0,i,2); } build(0,N-1,0); for (i = 0; i < M; i++) { int l = lca(S[i],T[i]); for (int o: {S[i],T[i]}) { int u = o; while (chain[u] != chain[l]) { int s = disc[head[chain[u]]],e = disc[u]; if (disc[S[i]] == s) s++; if (disc[S[i]] == e) e--; if (s <= e) add(0,N-1,s,e,0,i,1); s = disc[head[chain[u]]],e = disc[u]; if (disc[T[i]] == s) s++; if (disc[T[i]] == e) e--; if (s <= e) add(0,N-1,s,e,0,i,2); add(0,N-1,s,e,0,i,2); u = parent[head[chain[u]]][0]; } int s = disc[l],e = disc[u]; if (disc[S[i]] == s) s++; if (disc[S[i]] == e) e--; if (s <= e) add(0,N-1,s,e,0,i,1); s = disc[l],e = disc[u]; if (disc[T[i]] == s) s++; if (disc[T[i]] == e) e--; if (s <= e) add(0,N-1,s,e,0,i,2); } } fill(visited,visited+num,0),no = 0; for (i = 0; i < num; i++) { if (visited[i] == 0) doDFS2(i); } if (no) printf("No\n"); else printf("Yes\n"); clear(0,N-1,0); for (i = 0; i < N; i++) adjList[i].clear(); for (i = 0; i < num; i++) adjList2[i].clear(); } return 0; }

Compilation message (stderr)

jail.cpp: In function 'int main()':
jail.cpp:176:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  176 |     scanf("%d",&Q);
      |     ~~~~~^~~~~~~~~
jail.cpp:178:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  178 |         scanf("%d",&N);
      |         ~~~~~^~~~~~~~~
jail.cpp:180:18: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  180 |             scanf("%d %d",&A,&B);
      |             ~~~~~^~~~~~~~~~~~~~~
jail.cpp:185:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  185 |         scanf("%d",&M);
      |         ~~~~~^~~~~~~~~
jail.cpp:186:38: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  186 |         for (i = 0; i < M; i++) scanf("%d %d",&S[i],&T[i]),S[i]--,T[i]--;
      |                                 ~~~~~^~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...