답안 #757036

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
757036 2023-06-12T12:42:11 Z Sam_a17 Spring cleaning (CEOI20_cleaning) C++17
37 / 100
1000 ms 27540 KB
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
// #include <atcoder/all>
#include <cstdio>
using namespace std;
 
#ifndef ONLINE_JUDGE
#define dbg(x) cerr << #x <<" "; print(x); cerr << endl;
#else
#define dbg(x)
#endif
 
#define sz(x) (int((x).size()))
#define len(x) (int)x.length()
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define clr(x) (x).clear()
#define uniq(x) x.resize(unique(all(x)) - x.begin());
 
#define pb push_back
#define popf pop_front
#define popb pop_back
#define ld long double
#define ll long long
 
void print(long long t) {cerr << t;}
void print(int t) {cerr << t;}
void print(string t) {cerr << t;}
void print(char t) {cerr << t;}
void print(double t) {cerr << t;}
void print(unsigned long long t) {cerr << t;}
void print(long double t) {cerr << t;}
 
template <class T, class V> void print(pair <T, V> p);
template <class T> void print(vector <T> v);
template <class T> void print(set <T> v);
template <class T, class V> void print(map <T, V> v);
template <class T> void print(multiset <T> v);
template <class T> void print(T v[],T n) {cerr << "["; for(int i = 0; i < n; i++) {cerr << v[i] << " ";} cerr << "]";}
template <class T, class V> void print(pair <T, V> p) {cerr << "{"; print(p.first); cerr << ","; print(p.second); cerr << "}";}
template <class T> void print(vector <T> v) {cerr << "[ "; for (T i : v) {print(i); cerr << " ";} cerr << "]";}
template <class T> void print(deque <T> v) {cerr << "[ "; for (T i : v) {print(i); cerr << " ";} cerr << "]";}
template <class T> void print(set <T> v) {cerr << "[ "; for (T i : v) {print(i); cerr << " ";} cerr << "]";}
template <class T> void print(multiset <T> v) {cerr << "[ "; for (T i : v) {print(i); cerr << " ";} cerr << "]";}
template <class T, class V> void print(map <T, V> v) {cerr << "[ "; for (auto i : v) {print(i); cerr << " ";} cerr << "]";}
 
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
#define nl '\n'
 
// for random generations
mt19937 myrand(chrono::steady_clock::now().time_since_epoch().count());
// mt19937 myrand(131);
 
// for grid problems
int dx[8] = {-1,0,1,0,1,-1,1,-1};
int dy[8] = {0,1,0,-1,1,1,-1,-1};
 
long long ka() {
	long long x = 0;
	bool z = false;
	while (1)
	{
		char y = getchar();
		if (y == '-')
			z = true;
		else if ('0' <= y && y <= '9')
			x = x * 10 + y - '0';
		else
		{
			if (z)
				x *= -1;
			return x;
		}
	}
}
 
// lowest / (1 << 17) >= 1e5 / (1 << 18) >= 2e5 / (1 << 21) >= 1e6
void fastIO() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr); cout.tie(nullptr);
}
// file in/out
void setIO(string str = "") {
  fastIO();
 
  // if (str != "") {
  //   freopen((str + ".in").c_str(), "r", stdin);
  //   freopen((str + ".out").c_str(), "w", stdout);
  // }else {
    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);
  // }
}
 
// Indexed Set
template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
const int N = 2e5 + 10, M = 7e6 + 10;
vector<int> adj[N];
int n, q, deg[N];

int dp[N][3];
int depth[N];
bool is_leaf[N];

int sz[N], id[N], tp[N], p[N], dep[N];
struct node {
  long long sum, ones, twos, lazy;
};

node combine(node a, node b) {
  a.sum += b.sum;
  a.ones += b.ones;
  a.twos += b.twos;
  a.lazy = 0;
  return a;
}

struct segTree {

  vector<node> tree;
  int size = 1;
 
  void propagate(int x, int lx, int rx) {
    if(rx - lx == 1 || tree[x].lazy % 2 == 0) {
      tree[x].lazy = 0;
      return;
    }
 
    int mid = (lx + rx) / 2;
 
    tree[2 * x + 1].lazy += tree[x].lazy;
    swap(tree[2 * x + 1].ones, tree[2 * x + 1].twos);
    tree[2 * x + 1].sum = tree[2 * x + 1].ones + 2 * tree[2 * x + 1].twos;
 
    tree[2 * x + 2].lazy += tree[x].lazy;
    swap(tree[2 * x + 2].ones, tree[2 * x + 2].twos);
    tree[2 * x + 2].sum = tree[2 * x + 2].ones + 2 * tree[2 * x + 2].twos;


    tree[x].lazy = 0;
  }
 
  void init(long long s) {
    while(size < s) {
      size *= 2;
    }
    tree.assign(2 * size - 1, {0, 0, 0, 0});
  }
 
  void upd(int l, int r, long long value, int x, int lx, int rx) {
    propagate(x, lx, rx);
    if(lx >= r || rx <= l) {
      return;
    }
 
    if(lx >= l && rx <= r) {
      if(value % 2 == 1) {
        swap(tree[x].ones, tree[x].twos);
      }
      tree[x].sum = tree[x].ones + 2 * tree[x].twos;
      tree[x].lazy += value;
      propagate(x, lx, rx);
      return;
    }
 
    int mid = (lx + rx) / 2;
    upd(l, r, value, 2 * x + 1, lx, mid);
    upd(l, r, value, 2 * x + 2, mid, rx);
    tree[x] = combine(tree[2 * x + 1], tree[2 * x + 2]);
  }
 
  void upd(int l, int r, long long value) {
    upd(l, r, value, 0, 0, size);
  }

  void upd2(int l, int r, long long value, int x, int lx, int rx) {
    propagate(x, lx, rx);
    if(lx >= r || rx <= l) {
      return;
    }
 
    if(lx >= l && rx <= r) {
      if(value == 1) {
        tree[x].ones = 1;
      } else {
        tree[x].twos = 1;
      }
      tree[x].sum = tree[x].ones + 2 * tree[x].twos;
      tree[x].lazy = 0;
      propagate(x, lx, rx);
      return;
    }
 
    int mid = (lx + rx) / 2;
    upd2(l, r, value, 2 * x + 1, lx, mid);
    upd2(l, r, value, 2 * x + 2, mid, rx);
    tree[x] = combine(tree[2 * x + 1], tree[2 * x + 2]);
  }
 
  void upd2(int l, int r, long long value) {
    upd2(l, r, value, 0, 0, size);
  }
 
  node qry(int l, int r, int x, int lx, int rx) {
    propagate(x, lx, rx);
    if(lx >= r || rx <= l) {
      return {0, 0, 0, 0};
    }
 
    if(lx >= l && rx <= r) {
      return tree[x];
    }
 
    int mid = (lx + rx) / 2;
    node s1 = qry(l, r, 2 * x + 1, lx, mid);
    node s2 = qry(l, r, 2 * x + 2, mid, rx);
    return combine(s1, s2);
  }
 
  node qry(int l, int r) {
    return qry(l, r, 0, 0, size);
  }
};

segTree seg;

int dfs_sz(int cur, int par) {
	sz[cur] = 1;
	p[cur] = par;
	for (int chi : adj[cur]) {
		if (chi == par) continue;
		dep[chi] = dep[cur] + 1;
		p[chi] = cur;
		sz[cur] += dfs_sz(chi, cur);
	}
	return sz[cur];
}

int ct = 1;

void dfs_hld(int cur, int par, int top) {
	id[cur] = ct++;
	tp[cur] = top;

  if(dp[cur][2] != -1) {
    seg.upd2(id[cur], id[cur] + 1, 2);
  } else {
    seg.upd2(id[cur], id[cur] + 1, 1);
  }


	int h_chi = -1, h_sz = -1;
	for (int chi : adj[cur]) {
		if (chi == par) continue;
		if (sz[chi] > h_sz) {
			h_sz = sz[chi];
			h_chi = chi;
		}
	}
	if (h_chi == -1) return;
	dfs_hld(h_chi, cur, top);
	for (int chi : adj[cur]) {
		if (chi == par || chi == h_chi) continue;
		dfs_hld(chi, cur, chi);
	}
}

void change_path(int x, int y) {
  node answ = {0, 0, 0};
	while (tp[x] != tp[y]) {
		if (dep[tp[x]] < dep[tp[y]]) swap(x, y);
    seg.upd(id[tp[x]], id[x] + 1, 1);
		x = p[tp[x]];
	}
	if (dep[x] > dep[y]) swap(x, y);
  seg.upd(id[x], id[y] + 1, 1);
}

void dfs(int node, int parent) {
  dp[node][1] = dp[node][2] = -1;

  int cnt = 0;
  for(auto i: adj[node]) {
    if(i == parent) continue;
    cnt++;
    dfs(i, node);
  }

  if(!cnt) {
    dp[node][1] = 0;
    is_leaf[node] = 1;
  } else {
    long long s = 0, c = 0;
    for(auto i: adj[node]) {
      if(i == parent) continue;

      if(dp[i][1] != -1) {
        c += 1;
        s += dp[i][1] + 1;
      } else if(dp[i][2] != -1) {
        c += 2;
        s += dp[i][2] + 2;
      }
    }

    if(c & 1) {
      dp[node][1] = s;
    } else {
      dp[node][2] = s;
    }
  }
}

void solve_() {
  // cin >> n >> q;
  n = ka(), q = ka();

  for(int i = 1; i <= n - 1; i++) {
    int a, b; 
    a = ka(), b = ka();
    // cin >> a >> b;
    adj[a].push_back(b);
    adj[b].push_back(a);

    deg[a]++, deg[b]++;
  }

  int start = -1;
  for(int i = 1; i <= n; i++) {
    if(deg[i] > 1) {
      start = i;
      break;
    }
  }

  seg.init(n + 2);
  dfs(start, 0);
  dfs_sz(start, 0);
  dfs_hld(start, 0, 1);

  while(q--) {
    int d = ka();
    long long cur = 0;

    if(dp[start][1] != -1) {
      cur = 1;
    } else {
      cur = 2;
    }

    vector<pair<int, int>> vec;
    int ok = 0;
    for(int i = 1; i <= d; i++) {
      int a = ka();
      deg[a]++;

      if(a == start) {
        change_path(a, start);
        vec.push_back({a, 1});

        cur++;
        continue;
      } else if(deg[a] == 2) {
        vec.push_back({a, 0});

        continue;
      }

      cur++;
      change_path(a, start);
      vec.push_back({a, 1});
    }

    if(cur % 2 == 1) { 
      cout << -1 << '\n';
    } else {
      cout << seg.qry(2, n + 1).sum + d << '\n';
    }

    for(auto i: vec) {
      deg[i.first]--;
      if(i.second) {
        change_path(i.first, start);
      }
    }

  }
}
 
int main() {
  setIO();
 
  auto solve = [&](int test_case)-> void {
    while(test_case--) {
      solve_();
    }
  };
 
  int test_cases = 1; 
  // cin >> test_cases;
  solve(test_cases);
 
  return 0;
}

Compilation message

cleaning.cpp: In member function 'void segTree::propagate(int, int, int)':
cleaning.cpp:130:9: warning: unused variable 'mid' [-Wunused-variable]
  130 |     int mid = (lx + rx) / 2;
      |         ^~~
cleaning.cpp: In function 'void change_path(int, int)':
cleaning.cpp:270:8: warning: unused variable 'answ' [-Wunused-variable]
  270 |   node answ = {0, 0, 0};
      |        ^~~~
cleaning.cpp: In function 'void solve_()':
cleaning.cpp:353:9: warning: unused variable 'ok' [-Wunused-variable]
  353 |     int ok = 0;
      |         ^~
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4948 KB Output is correct
2 Correct 170 ms 8568 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 70 ms 6672 KB Output is correct
2 Correct 76 ms 6668 KB Output is correct
3 Correct 70 ms 20404 KB Output is correct
4 Correct 169 ms 19424 KB Output is correct
5 Correct 141 ms 21448 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 91 ms 7428 KB Output is correct
2 Correct 102 ms 7376 KB Output is correct
3 Correct 89 ms 27540 KB Output is correct
4 Correct 289 ms 27424 KB Output is correct
5 Correct 74 ms 26188 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 136 ms 9100 KB Output is correct
2 Correct 67 ms 8500 KB Output is correct
3 Correct 18 ms 8404 KB Output is correct
4 Execution timed out 1070 ms 9072 KB Time limit exceeded
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 240 ms 17868 KB Output is correct
2 Correct 361 ms 17876 KB Output is correct
3 Correct 295 ms 11436 KB Output is correct
4 Correct 364 ms 17768 KB Output is correct
5 Correct 346 ms 17700 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 321 ms 20552 KB Output is correct
2 Correct 282 ms 23272 KB Output is correct
3 Execution timed out 1100 ms 23020 KB Time limit exceeded
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4948 KB Output is correct
2 Correct 170 ms 8568 KB Output is correct
3 Correct 70 ms 6672 KB Output is correct
4 Correct 76 ms 6668 KB Output is correct
5 Correct 70 ms 20404 KB Output is correct
6 Correct 169 ms 19424 KB Output is correct
7 Correct 141 ms 21448 KB Output is correct
8 Correct 91 ms 7428 KB Output is correct
9 Correct 102 ms 7376 KB Output is correct
10 Correct 89 ms 27540 KB Output is correct
11 Correct 289 ms 27424 KB Output is correct
12 Correct 74 ms 26188 KB Output is correct
13 Correct 136 ms 9100 KB Output is correct
14 Correct 67 ms 8500 KB Output is correct
15 Correct 18 ms 8404 KB Output is correct
16 Execution timed out 1070 ms 9072 KB Time limit exceeded
17 Halted 0 ms 0 KB -