Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #pragma GCC optimize("Ofast,unroll-loops")
- #pragma GCC target("avx,avx2,fma")
- typedef long long LL;
- typedef pair<int, int> PII;
- typedef vector<int> VI;
- typedef long double db;
- #define MP make_pair
- #define PB push_back
- #define X first
- #define Y second
- #define FOR(i, a, b) for(int i = (a); i < (b); ++i)
- #define RFOR(i, b, a) for(int i = (b) - 1; i >= (a); --i)
- #define ALL(a) a.begin(), a.end()
- #define SZ(a) (int)((a).size())
- #define FILL(a, value) memset(a, value, sizeof(a))
- #define debug(a) cerr << #a << " = " << a << endl;
- template<typename T> void setmax(T& x, T y) {x = max(x, y);}
- template<typename T> void setmin(T& x, T y) {x = min(x, y);}
- template<typename T> void print(const T& a, ostream& out){
- for(auto i: a) out << i << ' ';
- out << endl;
- }
- const double PI = acos(-1.0);
- const LL INF = 1e9 + 47;
- const LL LINF = INF * INF;
- mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
- const int N = 50000 + 7;
- int n, q;
- int a[N];
- VI g[N];
- int tin[N], tout[N], timer;
- int sz[N];
- int parent[N];
- int w[N];
- int A[N];
- void dfs_sz(int v, int p){
- parent[v] = p;
- sz[v] = 1;
- for(auto& i: g[v]) if (i == p){
- swap(i, g[v].back());
- g[v].pop_back();
- break;
- }
- FOR(i, 0, SZ(g[v])){
- dfs_sz(g[v][i], v);
- sz[v] += sz[g[v][i]];
- if (sz[g[v][i]] > sz[g[v][0]]) swap(g[v][i], g[v][0]);
- }
- }
- void dfs_order(int v, int p){
- tin[v] = timer++;
- if (SZ(g[v]) > 0){
- w[g[v][0]] = w[v];
- }
- FOR(i, 0, SZ(g[v])){
- dfs_order(g[v][i], v);
- }
- tout[v] = timer;
- }
- inline int isAnc(int u, int v){
- return tin[u] <= tin[v] && tout[u] >= tout[v];
- }
- inline void add_seg(int l, int r){
- FOR(i, l, r) a[i] ^= 1;
- }
- inline void add(int u, int v){
- while(!isAnc(w[u], v)){
- add_seg(tin[w[u]], tin[u] + 1);
- u = parent[w[u]];
- }
- while(w[u] != w[v]){
- add_seg(tin[w[v]], tin[v] + 1);
- v = parent[w[v]];
- }
- add_seg(min(tin[u], tin[v]), max(tin[u], tin[v]) + 1);
- }
- vector<int> vec[N];
- const int magic = 1000;
- int Id[N];
- int ptr = 0;
- inline LL solve(int v){
- LL ans = 0;
- int all = 0, C = 0;
- all = a[tin[v]];
- if (SZ(g[v]) <= magic){
- for(auto i: g[v]){
- const int L = tin[i], R = tout[i];
- FOR(j, L, R) C += a[j];
- ans += all * (LL) C;
- all += C;
- C = 0;
- }
- }else{
- const int L = tin[v] + 1, R = tout[v];
- const auto& is = vec[Id[v]];
- FOR(i, L, R){
- if (is[i]){
- ans += all * (LL) C;
- all += C;
- C = 0;
- }
- C += a[i];
- }
- }
- ans += all * (LL) C;
- return ans;
- }
- int main()
- {
- ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
- cin >> n >> q;
- FOR(i, 0, n) cin >> a[i];
- FOR(i, 1, n){
- int u, v;
- cin >> u >> v;
- --u; --v;
- g[u].PB(v);
- g[v].PB(u);
- }
- dfs_sz(0, 0);
- iota(w, w + n, 0);
- dfs_order(0, 0);
- FOR(i, 0, n) A[tin[i]] = a[i];
- FOR(i, 0, n) a[i] = A[i];
- FOR(i, 0, n) if (SZ(g[i]) > magic){
- vector<int>& v = vec[ptr];
- v.assign(n, 0);
- for(auto j: g[i]) v[tin[j]] = true;
- Id[i] = ptr;
- ptr++;
- }
- while(q--){
- int typ, x;
- cin >> typ >> x;
- --x;
- if (typ == 1){
- add(0, x);
- }else{
- if (SZ(g[x]) == 0){
- cout << "0\n";
- continue;
- }
- cout << solve(x) << '\n';
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement