Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define int long long int
- #define double long double
- #define endl '\n'
- #define all(c) c.begin(),c.end()
- #define mp(x,y) make_pair(x,y)
- #define eb emplace_back
- #define tr(k,st,en) for(int k = st; k <= en ; k++)
- #define trb(k,en,st) for(int k = en; k >= st ; k--)
- #define test int TN; cin>>TN; tr(T,1,TN)
- #define mxe(c) max_element(all(c))
- #define mne(c) min_element(all(c))
- using namespace std;
- template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; }
- template < typename T_container, typename T = typename enable_if < !is_same<T_container, string>::value, typename T_container::value_type >::type > ostream & operator<<(ostream &os, const T_container &v) { os << '{'; string sep; for (const T &x : v) os << sep << x, sep = ", "; return os << '}'; }
- void dbg_out() { cerr << endl; }
- template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cerr << ' ' << H; dbg_out(T...); }
- #ifdef LOCAL
- #define dbg(...) cerr << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
- #else
- #define dbg(...)
- #endif
- typedef pair<int, int> pr;
- typedef vector<int> vi;
- typedef vector<vi> vvi;
- typedef vector<pr> vpr;
- //const int mod = 1e9+7;
- //const int inf = 9e18;
- const int N = 200005;
- vector<int> adj[N];
- int par[N];
- void dfs(int x, int p) {
- par[x] = p;
- for (int l : adj[x]) {
- if (l != p) dfs(l, x);
- }
- }
- int tme = 0;
- int tin[N], tout[N], val[N] , t_val[N];
- void dfs2(int x, int p, int cur) {
- tin[x] = tme++;
- t_val[tin[x]] = cur;
- for (int l : adj[x]) {
- if (l != p) {
- dfs2(l, x, cur ^ val[l]);
- }
- }
- tout[x] = tme;
- }
- int get_sqrt(int x) {
- int l = 1, r = x;
- while (l + 1 < r) {
- int m = (l + r) / 2;
- if (m * m <= x) {
- l = m;
- } else r = m;
- }
- return r;
- }
- class SqrtDecom {
- public:
- vector<int> arr;
- vector<unordered_map<int, int>> block;
- vector<int> lz;
- int sz;
- int b_sz;
- SqrtDecom(int * in, int n) {
- arr.resize(n);
- sz = arr.size();
- b_sz = get_sqrt(sz);
- block.resize(b_sz);
- lz.assign(b_sz, 0);
- for (int i = 0; i < n; i++) {
- block[i / b_sz][in[i]]++;
- arr[i] = in[i];
- }
- }
- int query(int x) {
- int rt = 0;
- for (int i = 0; i < b_sz; i++) {
- int tp = lz[i] ^ x;
- rt += block[i][tp];
- }
- return rt;
- }
- void update(int l, int r, int v) {
- int c_l = l / b_sz, c_r = r / b_sz;
- if (c_l == c_r)
- for (int i = l; i <= r; ++i) {
- block[c_l][arr[i]]--;
- arr[i] = arr[i] ^ v;
- block[c_l][arr[i]]++;
- }
- else {
- for (int i = l, end = (c_l + 1) * b_sz - 1; i <= end; ++i) {
- block[c_l][arr[i]]--;
- arr[i] = arr[i] ^ v;
- block[c_l][arr[i]]++;
- }
- for (int i = c_l + 1; i <= c_r - 1; ++i)
- lz[i] = lz[i] ^ v;
- for (int i = c_r * b_sz; i <= r; ++i) {
- block[c_r][arr[i]]--;
- arr[i] = arr[i] ^ v;
- block[c_r][arr[i]]++;
- }
- }
- }
- int get_val(int idx) {
- int p = lz[idx / b_sz];
- return arr[idx] ^ p;
- }
- };
- int32_t main() {
- std::ios::sync_with_stdio(false);
- cin.tie(NULL); cout.tie(NULL);
- int n, q;
- cin >> n >> q;
- vector<vector<int>> tmp;
- for (int i = 1; i < n; i++) {
- int u, v, w;
- cin >> u >> v >> w;
- tmp.emplace_back( vector<int>({u, v, w}));
- adj[u].push_back(v);
- adj[v].push_back(u);
- }
- dfs(1, 0);
- for (auto m : tmp) {
- int u = m[0], v = m[1], w = m[2];
- if (u != par[v]) {
- swap(u, v);
- }
- val[v] = w;
- }
- dfs2(1, 0, 0);
- SqrtDecom str(t_val, tme);
- for (int i = 0; i < q; i++) {
- int t;
- cin >> t;
- if (t == 1) {
- int x;
- cin >> x;
- int p = str.get_val(tin[x]);
- cout << str.query(p) << endl;
- } else {
- int u, v, w;
- cin >> u >> v >> w;
- if (u != par[v]) {
- swap(u, v);
- }
- str.update(tin[v], tout[v] - 1, val[v] ^ w);
- val[v] = w;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement