제출 #1119745

#제출 시각아이디문제언어결과실행 시간메모리
1119745Requiem동기화 (JOI13_synchronization)C++17
100 / 100
4265 ms49056 KiB
#include<bits/stdc++.h> #define int long long #define pb push_back #define fast ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); #define MOD 1000000007 #define inf 1e18 #define fi first #define se second #define FOR(i,a,b) for(int i=a;i<=b;i++) #define FORD(i,a,b) for(int i=a;i>=b;i--) #define sz(a) ((int)(a).size()) #define endl '\n' #define pi 3.14159265359 #define TASKNAME "synchronization" using namespace std; template<typename T> bool maximize(T &res, const T &val) { if (res < val){ res = val; return true; }; return false; } template<typename T> bool minimize(T &res, const T &val) { if (res > val){ res = val; return true; }; return false; } typedef pair<int,int> ii; typedef pair<int,ii> iii; typedef vector<int> vi; /** Cho 1 cây N đỉnh. Ta có các thao tác, bật tắt cạnh. Ta có q truy vấn: - với đỉnh u, hãy đếm số đỉnh từng cùng thành phần liên thông với u. Bài này dùng observation: Khi ta thêm 1 cạnh (u, v) vào kết quả của thành phần liên thông sẽ trở thành: ans_new = ans[u] + ans[v] - c. c: số thằng mà 2 thằng giống nhau. Trong đó c là kết quả của lần kết hợp gần nhất (c = 0, nếu chưa từng kết hợp) Nhưng ta không thể lưu kết quả cho tất cả các nút được nên ta sẽ lấy 1 nút làm đại diện (nút có độ cao thấp nhất trên cây **/ struct BinaryIndexedTree{ vector<int> BIT; BinaryIndexedTree(int sz = 0){ BIT.resize(sz + 9); } int get(int id){ int res = 0; for(int i = id; i > 0; i -= i & (-i)){ res += BIT[i]; } return res; } void update(int id, int x){ for(int i = id; i < BIT.size(); i += i & (-i)){ BIT[i] += x; } cerr << id << ' '<< x<<endl; } }; const int MAXN = 3e5 + 9; vector<int> g[MAXN]; ii edge[MAXN]; int n, m, q; BinaryIndexedTree opt; int dfsTime = 0; int del[MAXN], in[MAXN], out[MAXN], depth[MAXN], P[30][MAXN]; int ans[MAXN], ans_edge_before[MAXN]; void dfs(int u, int p){ P[0][u] = p; in[u] = ++dfsTime; for(auto id: g[u]){ int v = edge[id].se + edge[id].fi - u; if (v == p) continue; depth[v] = depth[u] + 1; dfs(v, u); } out[u] = dfsTime; } int jumpKth(int u, int k){ for(int i = 0; k > 0; k >>= 1, i++){ if (k&1) u = P[i][u]; } return u; } int root(int u){ int s = opt.get(in[u]); int l = 0, r = depth[u], res = 0; while(l <= r){ int mid = (l + r) >> 1; if (opt.get(in[ jumpKth(u, mid) ]) == s){ res = mid; l = mid + 1; } else{ r = mid - 1; } } return jumpKth(u, res); } void eraseEdge(int u){ opt.update(in[u], 1); opt.update(out[u] + 1, -1); } void addEdge(int u){ opt.update(in[u], -1); opt.update(out[u] + 1, 1); } void updateEdge(int id){ int u = edge[id].se; int p = root(edge[id].fi); if (del[id] == 0){ del[id] = 1; ans[u] = ans[p]; ans_edge_before[id] = ans[p]; } else{ ans[p] = ans[u] + ans[p] - ans_edge_before[id]; del[id] = 0; } if (del[id] == 1) eraseEdge(u); else addEdge(u); } main() { fast; if (fopen(TASKNAME".inp","r")){ freopen(TASKNAME".inp","r",stdin); freopen(TASKNAME".out","w",stdout); } cin >> n >> m >> q; FOR(i, 1, n - 1){ int u, v; cin >> u >> v; edge[i] = {u, v}; g[u].pb(i); g[v].pb(i); } fill(del, del + 1 + n, 1); dfs(1, -1); FOR(i, 1, 20){ FOR(j, 1, n){ if (P[i - 1][j] == -1) P[i][j] = -1; else P[i][j] = P[i - 1][P[i - 1][j]]; } } FOR(i, 1, n - 1){ if (depth[edge[i].fi] > depth[edge[i].se]) swap(edge[i].fi, edge[i].se); } opt = BinaryIndexedTree(n + 1); FOR(i, 1, n){ eraseEdge(i); ans[i] = 1; } FOR(i, 1, m){ int u; cin >> u; updateEdge(u); } FOR(i, 1, q){ int u; cin >> u; cout << ans[root(u)] << endl; } } /** Warning: Đọc sai đề??? Cận lmao Code imple thiếu case nào không. Limit. **/

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

synchronization.cpp: In member function 'void BinaryIndexedTree::update(long long int, long long int)':
synchronization.cpp:57:27: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   57 |         for(int i = id; i < BIT.size(); i += i & (-i)){
      |                         ~~^~~~~~~~~~~~
synchronization.cpp: At global scope:
synchronization.cpp:141:1: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
  141 | main()
      | ^~~~
synchronization.cpp: In function 'int main()':
synchronization.cpp:145:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  145 |         freopen(TASKNAME".inp","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
synchronization.cpp:146:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  146 |         freopen(TASKNAME".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...