답안 #399909

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
399909 2021-05-06T22:43:54 Z arwaeystoamneg 동기화 (JOI13_synchronization) C++17
30 / 100
1175 ms 29192 KB
// EXPLOSION!
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
#include<chrono>

using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<pair<int, int>> vpi;
typedef vector<pair<ll, ll>> vpll;

#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i,a) ROF(i,0,a)
#define trav(a,x) for (auto& a: x)

#define pb push_back
#define mp make_pair
#define rsz resize
#define sz(x) int(x.size())
#define all(x) x.begin(),x.end()
#define f first
#define s second
#define cont continue
#define endl '\n'
//#define ednl '\n'
#define test int testc;cin>>testc;while(testc--)
#define pr(a, b) trav(x,a)cerr << x << b; cerr << endl;
#define message cout << "Hello World" << endl;
const int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 }; // for every grid problem!!
const ll linf = 4000000000000000000LL;
const ll inf = 998244353;//998244353    1000000007

void pv(vi a) { trav(x, a)cout << x << " "; cout << endl; }void pv(vll a) { trav(x, a)cout << x << " "; cout << endl; }void pv(vector<vi>a) {
	F0R(i, sz(a)) { cout << i << endl; pv(a[i]); cout << endl; }
}void pv(vector<vll>a) { F0R(i, sz(a)) { cout << i << endl; pv(a[i]); }cout << endl; }void pv(vector<string>a) { trav(x, a)cout << x << endl; cout << endl; }
void setIO(string s) {
	ios_base::sync_with_stdio(0); cin.tie(0);
#ifdef arwaeystoamneg
	if (sz(s))
	{
		freopen((s + ".in").c_str(), "r", stdin);
		if (s != "test1")
			freopen((s + ".out").c_str(), "w", stdout);
	}
#endif
}
template<class T>class segment_tree
{
	struct item
	{
		T sum;
	};
	item single(T i)
	{
		return { i };
	}
	item merge(item x, item y)
	{
		item ans;
		ans.sum = x.sum + y.sum;
		return ans;
	}
	vector<item> tree;
	vector<item>A;
	int height;
	item neutral = { 0 };
public:void build(vector<T>& B)
{
	int	n = B.size();
	height = log2(n + 1) + 1;
	A.rsz(n);
	tree.rsz((1 << height + 1) - 1);
	F0R(i, n)A[i] = single(B[i]);
	A.rsz(1 << height, neutral);
	build(A, 0, 0, (1 << height) - 1);
}
	  void build(vector<item>& A, int v, int tl, int tr)
	  {
		  if (tl == tr)
			  tree[v] = A[tl];
		  else
		  {
			  int mid = (tl + tr) / 2;
			  build(A, 2 * v + 1, tl, mid);
			  build(A, 2 * v + 2, mid + 1, tr);
			  tree[v] = merge(tree[2 * v + 1], tree[2 * v + 2]);
		  }
	  }
public:T query(int l, int r)
{
	return query(0, 0, (1 << height) - 1, l, r).sum;
}
	  item query(int v, int tl, int tr, int l, int r)
	  {
		  if (r<tl || l>tr)return neutral;
		  if (l <= tl && r >= tr)
		  {
			  return tree[v];
		  }
		  int mid = (tl + tr) / 2;
		  return merge(query(2 * v + 1, tl, mid, l, r), query(2 * v + 2, mid + 1, tr, l, r));
	  }
	  //assign
public:void update(int pos, T val)
{
	update(0, 0, (1 << height) - 1, pos, single(val));
}
	  void update(int v, int tl, int tr, int pos, item val)
	  {
		  if (tl == tr)
		  {
			  tree[v] = merge(tree[v], val);
		  }
		  else
		  {
			  int mid = (tl + tr) / 2;
			  if (pos <= mid)
				  update(2 * v + 1, tl, mid, pos, val);
			  else
				  update(2 * v + 2, mid + 1, tr, pos, val);
			  tree[v] = merge(tree[2 * v + 1], tree[2 * v + 2]);
		  }
	  }
public:int get(int k)
{
	return get(0, 0, (1 << height) - 1, k);
}
	  int get(int v, int tl, int tr, int k)
	  {
		  if (tl == tr)return tl;
		  int mid = (tl + tr) / 2;
		  if (k > tree[2 * v + 1].sum)
			  return get(2 * v + 2, mid + 1, tr, k - tree[2 * v + 1].sum);
		  return get(2 * v + 1, tl, mid, k);
	  }
};

struct e
{
	int x, y;
	int ans;
	bool a;
	int get(int z)
	{
		return x + y - z;
	}
};
const int MAX = 100005, SZ = 20;
e edge[MAX];
int n, m, q, tin[MAX], order[MAX], sizes[MAX], ptr, parent[MAX], ans[MAX], jump[SZ][MAX];
vi adj[MAX];
segment_tree<int>sum;
void dfs(int i, int p = -1)
{
	sizes[i] = 1;
	parent[i] = p;
	tin[i] = ptr;
	order[ptr++] = i;
	trav(x, adj[i])
	{
		int j = edge[x].get(i);
		if (j == p)continue;
		dfs(j, i);
		sizes[i] += sizes[j];
	}
}
int get(int i, int c)
{
	R0F(j, SZ)
	{
		int k = jump[j][i];
		if (k == -1)continue;
		if (sum.query(0, tin[k]) == c)i = k;
	}
	return i;
}
int main()
{
	setIO("test1");
	cin >> n >> m >> q;
	F0R(i, n - 1)
	{
		int x, y;
		cin >> x >> y;
		edge[i] = { --x,--y,0,0 };
		adj[x].pb(i);
		adj[y].pb(i);
	}
	vi temp(n + 1, 1);
	sum.build(temp);
	dfs(0);
	F0R(i, n - 1)if (parent[edge[i].x] == edge[i].y)swap(edge[i].x, edge[i].y);
	fill(ans, ans + n, 1);
	F0R(i, n)jump[0][i] = parent[i];
	F0R(i, SZ - 1)
	{
		F0R(j, n)
		{
			jump[i + 1][j] = (jump[i][j] == -1 ? -1 : jump[i][jump[i][j]]);
		}
	}
	while (m--)
	{
		int i;
		cin >> i;
		i--;
		if (edge[i].a == 0)
		{
			int c = sum.query(0, tin[edge[i].x]);
			int j = get(edge[i].x, c);
			ans[j] += ans[edge[i].y] - edge[i].ans;
			int d = sum.query(0, tin[j]) - sum.query(0, tin[edge[i].y]);
			sum.update(tin[edge[i].y], d);
			sum.update(tin[edge[i].y] + sizes[edge[i].y], -d);
		}
		else
		{
			int c = sum.query(0, tin[edge[i].x]);
			int j = get(edge[i].x, c);
			edge[i].ans = ans[j];
			ans[edge[i].y] = ans[j];
			int d = edge[i].y + 1 - sum.query(0, tin[edge[i].y] - 1);
			sum.update(tin[edge[i].y], d);
			sum.update(tin[edge[i].y] + sizes[edge[i].y], -d);
		}
		edge[i].a ^= 1;
	}
	while (q--)
	{
		int i;
		cin >> i;
		i--;
		int c = sum.query(0, tin[i]);
		int j = get(i, c);
		cout << ans[j] << endl;
	}
}

Compilation message

synchronization.cpp: In instantiation of 'void segment_tree<T>::build(std::vector<_Tp>&) [with T = int]':
synchronization.cpp:198:16:   required from here
synchronization.cpp:80:24: warning: suggest parentheses around '+' inside '<<' [-Wparentheses]
   80 |  tree.rsz((1 << height + 1) - 1);
      |                 ~~~~~~~^~~
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2764 KB Output is correct
2 Correct 2 ms 2764 KB Output is correct
3 Correct 2 ms 2764 KB Output is correct
4 Correct 2 ms 2700 KB Output is correct
5 Correct 2 ms 2764 KB Output is correct
6 Correct 4 ms 2892 KB Output is correct
7 Correct 31 ms 4684 KB Output is correct
8 Correct 31 ms 4684 KB Output is correct
9 Correct 32 ms 4716 KB Output is correct
10 Correct 495 ms 21460 KB Output is correct
11 Correct 521 ms 21480 KB Output is correct
12 Correct 947 ms 29192 KB Output is correct
13 Correct 228 ms 21300 KB Output is correct
14 Correct 315 ms 20832 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 251 ms 23188 KB Output is correct
2 Correct 242 ms 25136 KB Output is correct
3 Correct 280 ms 28528 KB Output is correct
4 Correct 292 ms 28612 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2764 KB Output is correct
2 Correct 2 ms 2764 KB Output is correct
3 Incorrect 2 ms 2764 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1175 ms 27028 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2764 KB Output is correct
2 Incorrect 2 ms 2768 KB Output isn't correct
3 Halted 0 ms 0 KB -