Submission #80295

#TimeUsernameProblemLanguageResultExecution timeMemory
80295mbvdkUsmjeri (COCI17_usmjeri)C++14
140 / 140
1358 ms162356 KiB
#include <bits/stdc++.h> using namespace std; const int mod = 1e9+7; const int N = 300000; typedef long long ll; typedef pair<int, int> pii; int p[N+5]; int find(int a){ return p[a] == a?a:(p[a]=find(p[a])); } void uni(int a, int b){ a = find(a), b = find(b); if(a != b) p[a] = b; } struct hld{ vector<pii> g[N+5]; int chainIdx[N+5]; int chainHead[N+5]; int baseArr[N+5]; int posArr[N+5]; int chainNo = 1; int idx = 1; int depth[N+5]; int par[20][N+5]; int ss[N+5]; int st[4*N+5]; int lazy[4*N+5]; int n = N; void init(int m){ n = m; chainNo = 1; idx = 1; for(int i=1;i<=n;i++){ g[i].clear(); chainIdx[i] = 0; chainHead[i] = 0; baseArr[i] = 0; posArr[i] = 0; g[i].clear(); for(int j=0;j<20;j++) par[j][i] = 0; } } void build(int n, int s, int e){ if(s == e) st[n] = baseArr[s]; else{ int mid = (s+e)/2; build(n*2, s, mid); build(n*2+1, mid+1, e); st[n] = max(st[n*2], st[n*2+1]); } } void update(int n, int s, int e, int l, int r, int v){ if(lazy[n]){ st[n] |= lazy[n]; if(s != e){ lazy[n+n] |= lazy[n]; lazy[n+n+1] |= lazy[n]; } lazy[n] = 0; } if(s > r || l > e) return; if(l <= s && e <= r){ st[n] |= v; if(s != e){ lazy[n+n] |= v; lazy[n+n+1] |= v; } return; } int mid = (s+e)/2; update(n*2, s, mid, l, r, v); update(n*2+1, mid+1, e, l, r, v); st[n] = st[n+n] | st[n+n+1]; } int query(int n, int s, int e, int l, int r){ if(lazy[n]){ st[n] |= lazy[n]; if(s != e){ lazy[n+n] |= lazy[n]; lazy[n+n+1] |= lazy[n]; } lazy[n] = 0; } if(s > r || l > e) return 0; if(l <= s && e <= r) return st[n]; int mid = (s+e)/2; int p1 = query(n*2, s, mid, l, r); int p2 = query(n*2+1, mid+1, e, l, r); return p1 | p2; } int LCA(int a, int b){ if(depth[a] < depth[b]) swap(a, b); int diff = depth[a] - depth[b]; for(int i=19;i>=0;i--){ if((diff>>i)&1) a = par[i][a]; } if(a == b) return a; for(int i=19;i>=0;i--){ if(par[i][a] != par[i][b]) a = par[i][a], b = par[i][b]; } return par[0][a]; } void addEdge(int a, int b, int c){ g[a].push_back(pii(b, c)); g[b].push_back(pii(a, c)); } void dfs(int u, int p, int d){ depth[u] = d; par[0][u] = p; ss[u] = 1; for(int i=0;i<g[u].size();i++){ int v = g[u][i].first; if(v == p) continue; dfs(v, u, d+1); ss[u] += ss[v]; } } void decompose(int u, int p, int c){ if(chainHead[chainNo] == 0) chainHead[chainNo] = u; chainIdx[u] = chainNo; posArr[u] = idx; baseArr[idx++] = c; int nc = 0, pos = -1, sz = 0; for(int i=0;i<g[u].size();i++){ int v = g[u][i].first; int w = g[u][i].second; if(v == p) continue; if(ss[v] > sz){ sz = ss[v]; pos = v; nc = w; } } if(pos != -1) decompose(pos, u, nc); for(int i=0;i<g[u].size();i++){ int v = g[u][i].first; int w = g[u][i].second; if(v == p || v == pos) continue; chainNo++; decompose(v, u, w); } } int query_up(int u, int v){ int res = 0; while(1){ int uchain = chainIdx[u]; int vchain = chainIdx[v]; if(uchain == vchain){ if(u != v) res = res|query(1, 1, idx, posArr[v]+1, posArr[u]); break; } res = res|query(1, 1, idx, posArr[chainHead[uchain]], posArr[u]); u = chainHead[uchain]; u = par[0][u]; } return res; } void update_up(int u, int v, int val){ while(1){ int uchain = chainIdx[u]; int vchain = chainIdx[v]; if(uchain == vchain){ if(u != v) update(1, 1, idx, posArr[v]+1, posArr[u], val); break; } update(1, 1, idx, posArr[chainHead[uchain]], posArr[u], val); u = chainHead[uchain]; u = par[0][u]; } } void getParent(){ for(int j=1;j<=19;j++){ for(int i=1;i<=n;i++){ if(par[j-1][i] != 0) par[j][i] = par[j-1][par[j-1][i]]; } } } }hld; vector<int> dp[300005]; int a[300005], b[300005]; ll ans = 0; bool ok = 1; vector<int> ins[300005]; set<int> dp3[300005]; set<int>::iterator its; void dfs(int u, int p){ for(int i=0;i<dp[u].size();i++){ int idx = dp[u][i]; if(u == a[idx]){ int q1 = hld.query_up(b[idx], u); if(q1 == 0) hld.update_up(b[idx], u, 2); else if(q1 == 1) hld.update_up(b[idx], u, 1); else if(q1 == 2) hld.update_up(b[idx], u, 2); else ok = 0; } else{ int q1 = hld.query_up(a[idx], u); int q2 = hld.query_up(b[idx], u); if(q1 == 3 || q2 == 3){ ok = 0; } else if(q1 == 0 && q2 == 0){ hld.update_up(a[idx], u, 1); hld.update_up(b[idx], u, 2); } else if(q1 == 0){ hld.update_up(a[idx], u, 3-q2); hld.update_up(b[idx], u, q2); } else if(q2 == 0){ hld.update_up(a[idx], u, q1); hld.update_up(b[idx], u, 3-q1); } else if(q1 == q2){ ok = 0; } else{ hld.update_up(a[idx], u, q1); hld.update_up(b[idx], u, q2); } } } for(int i=0;i<hld.g[u].size();i++){ int v = hld.g[u][i].first; if(v == p) continue; dfs(v, u); if(dp3[u].size() < dp3[v].size()){ swap(dp3[u], dp3[v]); } for(its = dp3[v].begin();its != dp3[v].end();its++){ dp3[u].insert(*its); } } while(!dp3[u].empty() && -*dp3[u].begin() == hld.depth[u]-1){ dp3[u].erase(dp3[u].begin()); } if(!dp3[u].empty()) uni(u, p); } int main(){ int n, m; scanf("%d%d", &n, &m); hld.init(n); for(int i=2;i<=n;i++){ int a, b; scanf("%d%d", &a, &b); hld.addEdge(a, b, 0); p[i] = i; } hld.dfs(1, 0, 0); hld.getParent(); hld.decompose(1, 0, 0); hld.build(1, 1, hld.idx); for(int i=1;i<=m;i++){ scanf("%d%d", &a[i], &b[i]); int lca = hld.LCA(a[i], b[i]); if(lca == b[i]) swap(a[i], b[i]); dp[lca].emplace_back(i); if(lca == a[i]){ dp3[b[i]].insert(-hld.depth[lca]); } else{ uni(a[i], b[i]); dp3[a[i]].insert(-hld.depth[lca]); dp3[b[i]].insert(-hld.depth[lca]); } } dfs(1, 0); if(!ok) printf("0\n"); else{ ll ans = 1; for(int i=2;i<=n;i++){ int p = hld.posArr[i]; int q = hld.query(1, 1, hld.idx, p, p); if(find(i) == i) ans = (ans*2)%mod; } printf("%lld\n", ans); } }

Compilation message (stderr)

usmjeri.cpp: In member function 'void hld::dfs(int, int, int)':
usmjeri.cpp:111:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int i=0;i<g[u].size();i++){
               ~^~~~~~~~~~~~
usmjeri.cpp: In member function 'void hld::decompose(int, int, int)':
usmjeri.cpp:124:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int i=0;i<g[u].size();i++){
               ~^~~~~~~~~~~~
usmjeri.cpp:135:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int i=0;i<g[u].size();i++){
               ~^~~~~~~~~~~~
usmjeri.cpp: In function 'void dfs(int, int)':
usmjeri.cpp:188:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=0;i<dp[u].size();i++){
              ~^~~~~~~~~~~~~
usmjeri.cpp:224:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=0;i<hld.g[u].size();i++){
              ~^~~~~~~~~~~~~~~~
usmjeri.cpp: In function 'int main()':
usmjeri.cpp:275:8: warning: unused variable 'q' [-Wunused-variable]
    int q = hld.query(1, 1, hld.idx, p, p);
        ^
usmjeri.cpp:242:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d%d", &n, &m);
  ~~~~~^~~~~~~~~~~~~~~~
usmjeri.cpp:246:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d%d", &a, &b);
   ~~~~~^~~~~~~~~~~~~~~~
usmjeri.cpp:255:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d%d", &a[i], &b[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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...