제출 #1283449

#제출 시각아이디문제언어결과실행 시간메모리
1283449huyngodzzSpring cleaning (CEOI20_cleaning)C++20
100 / 100
324 ms18968 KiB
///huynhocute123/// #include<bits/stdc++.h> using namespace std; #define S second #define F first #define pii pair<int,int> #define piii pair<int,pair<int,int>> #define pb push_back #define FOR(i, a, b) for(int i = a; i <= b; ++i) #define REP(i, a, b) for(int i = b; i >= a; --i) #define ALL(v) v.begin(),v.end() #define inp(name) if(fopen(name, "r")) freopen(name, "r", stdin); #define out(name) if(fopen(name, "w")) freopen(name, "w", stdout); //random_device rd; //mt19937 rng(rd()); //#pragma GCC optimize ("O3") //#pragma GCC optimize ("unroll-loops") //#pragma GCC target("popcnt") //#define int long long const int MAX = 1e9+9; const long long MAXLL = 1e18+9; const double pi = 3.14159265358979323846; const double rad = 3.14159265358979323846 /180; bool minimize(int &u, int v){ if(v < u){ u = v; return 1; } return 0; } bool maximize(int &u, int v){ if(v > u){ u = v; return 1; } return 0; } bool maximizell(long long &u, long long v){ if(v > u){ u = v; return 1; } return 0; } bool minimizell(long long &u, long long v){ if(v < u){ u = v; return 1; } return 0; } const int mod = 1e9 + 7; inline int fastPow(int a, int n){ if(n == 0) return 1; int t = fastPow(a, n >> 1); t = 1ll * t * t % mod; if(n & 1) t = 1ll * t * a % mod; return t; } const int maxN = 1e5 + 99 ; int n, q; vector<int> e[maxN]; bool leaf[maxN], ok[maxN]; int sz[maxN] ,par[maxN]; int head[maxN] , chain[maxN] , pos[maxN] , ar[maxN], c_chain, c_pos; int Count_leaf[maxN]; void pre(int u ,int p){ // cout << u << '\n'; sz[u] = 1; for(auto x : e[u]){ if(x == p)continue; par[x] = u; pre(x ,u); sz[u] = sz[u] + sz[x]; Count_leaf[u] += Count_leaf[x]; } if(e[u].size() == 1){ Count_leaf[u]++; leaf[u] = 1; ok[u] = 1; } } void hld(int u ,int p){ if(!head[c_chain])head[c_chain] = u; chain[u] = c_chain; pos[u] = ++c_pos; ar[c_pos] = u; int nxt = 0; for(auto x : e[u]){ if(x == p)continue; if(nxt == 0 || sz[x] > sz[nxt])nxt = x; } if(nxt)hld(nxt, u); for(auto x : e[u]){ if(x == p || x == nxt)continue; ++c_chain; hld(x, u); } } pii st[4 * maxN]; int lazy[4 * maxN]; void push(int id){ if(lazy[id] == 0)return; st[id << 1].F = st[id << 1].S - st[id << 1].F; st[id << 1 | 1].F = st[id << 1 | 1].S - st[id << 1 | 1].F; lazy[id << 1] ^= 1; lazy[id << 1 | 1] ^= 1; lazy[id] = 0; } pii Merge(pii X , pii Y){ return make_pair(X.F + Y.F , X.S + Y.S); } void build(int id, int l ,int r){ if(l == r){ st[id] = make_pair( (Count_leaf[ar[l]] & 1 ) ? 1 : 2 , 3); // cerr << l << " " << ar[l] << " " <<Count_leaf[ar[l]] <<" " << st[id].F << '\n'; return; } int mid = (l + r)/2; build(id << 1, l ,mid); build(id << 1 | 1,mid + 1, r); st[id] = Merge(st[id << 1] ,st[id << 1 | 1]); } void upd(int id ,int l ,int r ,int u ,int v){ if(v < l || u > r)return; if(u <= l && r <= v){ st[id].F = st[id].S - st[id].F; lazy[id] ^= 1; return; } int mid = (l +r)/2; push(id); upd(id << 1, l ,mid , u ,v); upd(id << 1 | 1,mid + 1, r , u ,v); st[id] = Merge(st[id << 1 ] ,st[id << 1 | 1]); } pii get(int id, int l ,int r ,int u,int v){ if(v < l || u > r)return make_pair(0 , 0); if(u <= l && r <= v)return st[id]; int mid = (l + r)/2; push(id); return Merge(get(id << 1 ,l , mid , u ,v) , get(id << 1 | 1, mid + 1, r, u , v)); } int path_upd(int u ,int v){ int delta = 0; while(1){ if(chain[u] != chain[v]){ if(chain[u] < chain[v])swap(u ,v); int top = head[chain[u]]; pii X = get(1, 1, n , pos[top], pos[u]); // cout << X.F << " " << X.S << '\n'; delta += -2 * X.F + X.S; upd(1, 1, n , pos[top], pos[u]); u = par[top]; }else{ int l = min(pos[u] , pos[v]); int r = max(pos[u] , pos[v]); pii X = get(1, 1, n , l + 1, r ); // cout << X.F << " " << X.S << '\n'; delta += -2 * X.F + X.S; upd(1, 1, n , l + 1, r); break; } } // cout << delta << " "; return delta; } inline void solve(){ cin >> n >> q; FOR(i, 2 ,n){ int u ,v ;cin >> u >> v; e[u].pb(v); e[v].pb(u); } pre(1, 0); c_chain = 1; c_pos = 0; hld(1, 0); build(1, 1 ,n); // cout << path_upd(4, 1); FOR(xccx ,1 , q){ vector<int> ar; int sz;cin >> sz; FOR(i, 1 ,sz){ int x; cin >> x; ar.pb(x); } int cur_leaf = Count_leaf[1]; for(auto x : ar){ if(leaf[x] == 0)++cur_leaf; else{ if(ok[x])ok[x] = 0; else ++cur_leaf; } } for(auto x : ar)ok[x] = 1; if(cur_leaf & 1){ cout << -1 << '\n'; continue; } int cur_ans = get(1, 1, n, 2, n).F; vector<int> change; for(auto x : ar){ if(leaf[x]){ if(ok[x])ok[x] = 0; else{ change.pb(x); cur_ans += path_upd(x , 1); } }else { change.pb(x); cur_ans += path_upd(x , 1); } } for(auto x : change)path_upd(x ,1); cout << cur_ans + sz << '\n'; cerr << cur_ans + sz << '\n'; for(auto x : ar)ok[x] = 1; // cout << get(1, 1, n, 2, n).F << '\n'; } // cout << get(1, 1, n , pos[6] ,pos[6]) <<'\n'; // cout << get(1, 1, n ,2 , n) << '\n'; // cout << st[1].F; } signed main(){ ios_base::sync_with_stdio(false); cin.tie(0); #define NAME "task" if(fopen(NAME".inp", "r")){ freopen(NAME".inp", "r" ,stdin); freopen(NAME".out", "w" ,stdout); } int tc = 1; // cin >> tc; while( tc-- )solve(); cerr << '\n' << "Time elapsed: " << (1.0 * clock() / CLOCKS_PER_SEC) << " s\n" ; }

컴파일 시 표준 에러 (stderr) 메시지

cleaning.cpp: In function 'int main()':
cleaning.cpp:235:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  235 |         freopen(NAME".inp", "r" ,stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
cleaning.cpp:236:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  236 |         freopen(NAME".out", "w" ,stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#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...