Submission #105706

#TimeUsernameProblemLanguageResultExecution timeMemory
105706Pro_ktmr전압 (JOI14_voltage)C++14
100 / 100
493 ms33268 KiB
#include"bits/stdc++.h" using namespace std; #define LL long long #define REP(i, n) for(int (i)=0; (i)<(n); (i)++) #define PB push_back #define MP make_pair #define all(x) x.begin(),x.end() struct SegmentTree{ private: int n; vector<long long> nodes; public: void init(int N){ //初期化する O(N) nodes.clear(); n = 1; while(n < N) n *= 2; n = 2 * n -1; for(int i=0; i<n; i++) nodes.push_back(LLONG_MAX); } void update(int i, long long x){ //値を変更する O(log N) i += n / 2; nodes[i] = x; while(i > 0){ i = (i-1)/2; //親の取得は(i-1)/2 nodes[i] = min(nodes[i*2+1], nodes[i*2+2]); //子の取得はi*2+1,i*2+2 } } long long minimum(int a, int b, int k=0, int l=0, int r=-1){ //[a,b)の最小値を求める O(log N) if(r == -1) r = n/2+1; if(r <= a || b <= l) return LLONG_MAX; //交差する場合 if(a <= l && r <= b) return nodes[k]; //完全に含む場合 long long valueL = minimum(a, b, k*2+1, l, (l+r)/2); long long valueR = minimum(a, b, k*2+2, (l+r)/2, r); return min(valueL, valueR); } long long m; long long find(int a, int b, int k=0, int l=0, int r=-1){ if(r == -1){ m = minimum(a, b); r = (n+1)/2; } if(r <= a || b <= l) return LLONG_MAX; //交差する場合 if(r-l == 1){ if(nodes[k] == m) return l; else return LLONG_MAX; } if(a <= l && r <= b){ //完全に含む場合 long long valueL = minimum(a, b, k*2+1, l, (l+r)/2); long long valueR = minimum(a, b, k*2+2, (l+r)/2, r); if(valueL <= valueR) return find(a, b, k*2+1, l, (l+r)/2); else return find(a, b, k*2+2, (l+r)/2, r); } long long valueL = find(a, b, k*2+1, l, (l+r)/2); long long valueR = find(a, b, k*2+2, (l+r)/2, r); return min(valueL, valueR); } }; int N,M; vector<pair<int,int> > edge; bool ki[200000] = {}; vector<pair<int,int> > tonari[100000]; bool already[100000] = {}; int dfs_order[100000]; int par[100000]; vector<int> child[100000]; int c = 0; vector<pair<int,int> > other; void dfs(int now){ int next = c-1; for(int i=0; i<tonari[now].size(); i++){ if(already[tonari[now][i].first]) continue; already[tonari[now][i].first] = true; ki[tonari[now][i].second] = true; par[c] = next; dfs_order[tonari[now][i].first] = c; child[next].push_back(c); c++; dfs(tonari[now][i].first); } } int d[100000] = {}; int depth(int i){ if(par[i] == i) return 0; if(d[i] != 0) return d[i]; return d[i] = 1 + depth(par[i]); } vector<int> order; int pre[100000]; void dfs2(int now){ pre[now] = order.size(); order.push_back(now); for(int i=0; i<child[now].size(); i++){ dfs2(child[now][i]); order.push_back(now); } } SegmentTree st; int lca(int a, int b){ //cout << a << " " << b << " " << pre[a] << " " << pre[b] << " " << st.minimum(pre[a], pre[b]+1) << endl; a = pre[a]; b = pre[b]; if(a > b) swap(a,b); return (int)(st.minimum(a, b+1)); } int shouldChange[100000] = {}; int notChange[100000] = {}; int ans = 0; int main(){ cin >> N >> M; for(int i=0; i<M; i++){ int a,b; cin >> a >> b; a--; b--; tonari[a].push_back(MP(b,i)); tonari[b].push_back(MP(a,i)); edge.push_back(MP(a,b)); } for(int i=0; i<N; i++){ if(already[i]) continue; already[i] = true; par[c] = c; dfs_order[i] = c; c++; dfs(i); } for(int i=0; i<M; i++){ if(ki[i]) continue; other.push_back(MP(dfs_order[edge[i].first], dfs_order[edge[i].second])); } //for(int i=0; i<N; i++) cout << par[i] << endl; //for(int i=0; i<other.size(); i++) cout << other[i].first << " " << other[i].second << endl; //for(int i=0; i<N; i++){ // for(int j=0; j<child[i].size(); j++){ // cout << child[i][j] << " "; // } // cout << endl; //} // int tmp = 0; for(int i=0; i<other.size(); i++){ if(depth(other[i].first)%2 == depth(other[i].second)%2) tmp++; } if(tmp == 1) ans++; //cout << tmp << endl; // for(int i=0; i<N; i++){ if(par[i] != i) continue; dfs2(i); } //for(int i=0; i<order.size(); i++) cout << order[i] << (i==order.size()-1 ? "\n" : " "); st.init(order.size()); for(int i=0; i<order.size(); i++) st.update(i, order[i]); // int count = 0; for(int i=0; i<other.size(); i++){ //cout << other[i].first << " " << other[i].second << " " << lca(other[i].first, other[i].second) << endl; if(depth(other[i].first)%2 == depth(other[i].second)%2){ count++; shouldChange[other[i].first] += 1; shouldChange[other[i].second] += 1; shouldChange[lca(other[i].first, other[i].second)] -= 2; } else{ notChange[other[i].first] += 1; notChange[other[i].second] += 1; notChange[lca(other[i].first, other[i].second)] -= 2; } } vector<pair<int,int> > d_i; for(int i=0; i<N; i++){ d_i.push_back(MP(depth(i),i)); } sort(d_i.begin(), d_i.end()); reverse(d_i.begin(), d_i.end()); for(int i=0; i<N; i++){ if(par[d_i[i].second] == d_i[i].second) continue; shouldChange[par[d_i[i].second]] += shouldChange[d_i[i].second]; notChange[par[d_i[i].second]] += notChange[d_i[i].second]; } // for(int i=0; i<N; i++){ if(par[i] == i) continue; //cout << notChange[i] << " " << shouldChange[i] << endl; if(notChange[i] == 0 && shouldChange[i] == count) ans++; } // cout << ans << endl; return 0; }

Compilation message (stderr)

voltage.cpp: In function 'void dfs(int)':
voltage.cpp:73:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=0; i<tonari[now].size(); i++){
               ~^~~~~~~~~~~~~~~~~~~
voltage.cpp: In function 'void dfs2(int)':
voltage.cpp:97:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=0; i<child[now].size(); i++){
               ~^~~~~~~~~~~~~~~~~~
voltage.cpp: In function 'int main()':
voltage.cpp:152:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=0; i<other.size(); i++){
               ~^~~~~~~~~~~~~
voltage.cpp:166:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=0; i<order.size(); i++) st.update(i, order[i]);
               ~^~~~~~~~~~~~~
voltage.cpp:171:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i=0; i<other.size(); 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...