Submission #1352404

#TimeUsernameProblemLanguageResultExecution timeMemory
1352404SmuggingSpunSprinkler (JOI22_sprinkler)C++20
71 / 100
574 ms58512 KiB
#include<bits/stdc++.h>
#define taskname "B"
using namespace std;
typedef long long ll;
template<class T>void minimize(T& a, T b){
  if(a > b){
    a = b;
  }
}
const int lim_n = 2e5 + 5;
const int lim_q = 4e5 + 5;
int n, q, mod, a[lim_n];
void mul_mod(int& x, int y){
  x = ll(x) * y % mod;
}
vector<int>g[lim_n];
struct Query{
  int x, d, w;
  Query(){}
  Query(int _x, int _d, int _w) : x(_x), d(_d), w(_w) {}
};
Query query[lim_q];
namespace sub1{
  void solve(){
    for(int i = 1; i <= q; i++){
      auto& [x, d, w] = query[i];
      if(d != -1){
        queue<int>q;
        vector<int>h(n + 1, -1);
        q.push(x);
        h[x] = 0;
        while(!q.empty()){
          int u = q.front();
          q.pop();
          if(h[u] <= d){
            mul_mod(a[u], w);
          }
          for(int& v : g[u]){
            if(h[v] == -1){
              h[v] = h[u] + 1;
              q.push(v);
            }
          }
        }
      }
      else{
        cout << a[x] << "\n";
      }
    }
  }
}
namespace sub2{
  const int SIZE = 400;
  bool check_subtask(){
    for(int i = 1; i <= q; i++){
      if(abs(query[i].d) > 1){
        return false;
      }
    }
    return true;
  }
  void solve(){
    vector<int>par(n + 1);
    function<void(int)>dfs;
    dfs = [&] (int s){
      for(int& d : g[s]){
        if(d != par[s]){
          par[d] = s;
          dfs(d);
        }
      }
    };
    dfs(par[1] = 1);
    vector<pair<int, int>>contem;
    for(int i = 1; i <= q; i++){
      auto& [x, d, w] = query[i];
      if(d == 0){
        mul_mod(a[x], w);
      }
      else if(d == 1){
        contem.push_back(make_pair(x, w));
      }
      else{
        int ans = a[x];
        for(auto& [v, m] : contem){
          if(x == v || par[x] == v || par[v] == x){
            mul_mod(ans, m);
          }
        }
        cout << ans << "\n";
      }
      if(contem.size() == SIZE){
        sort(contem.begin(), contem.end());
        contem.push_back(make_pair(-1, 0));
        for(int i = 1, v = contem[0].second; i <= SIZE; i++){
          if(contem[i].first != contem[i - 1].first){
            for(int& other : g[contem[i - 1].first]){
              mul_mod(a[other], v);
            }
            mul_mod(a[contem[i - 1].first], v);
            v = contem[i].second;
          }
          else{
            mul_mod(v, contem[i].second);
          }
        }
        contem.clear();
      }
    }
  }
}
const int lim_d = 41;
namespace sub4{
  bool check_subtask(){
    for(int i = 1; i <= q; i++){
      if(query[i].w > 0){
        return false;
      }
    }
    return true;
  }
  void solve(){
    vector<int>st(n << 2 | 3, lim_n);
    function<void(int, int)>update = [&] (int p, int x){
      int id = 1, l = 1, r = n;
      while(l < r){
        minimize(st[id], x);
        int m = (l + r) >> 1;
        id <<= 1;
        if(m < p){
          id |= 1;
          l = m + 1;
        }
        else{
          r = m;
        }
      }
      minimize(st[id], x);
    };
    function<int(int, int, int, int, int)>get;
    get = [&] (int id, int l, int r, int u, int v){
      if(l > v || r < u){
        return lim_n;
      }
      if(u <= l && v >= r){
        return st[id];
      }
      int m = (l + r) >> 1;
      return min(get(id << 1, l, m, u, v), get(id << 1 | 1, m + 1, r, u, v));
    };
    vector<int>par(n + 1), h(n + 1), low(n + 1), tail(n + 1);
    int tdfs = par[1] = h[1] = 0;
    function<void(int)>dfs;
    dfs = [&] (int s){
      low[s] = +tdfs;
      for(int& d : g[s]){
        if(d != par[s]){
          h[d] = h[par[d] = s] + 1;
          dfs(d);
        }
      }
      tail[s] = tdfs;
    };
    dfs(1);
    for(int i = 1; i <= q; i++){
      auto& [x, d, w] = query[i];
      if(d != -1){
        update(low[x], h[x] - d);
      }
      else{
        int ans = a[x];
        for(int i = 0; i < lim_d; i++){
          if(get(1, 1, n, low[x], tail[x]) <= h[x] - i){
            ans = 0;
            break;
          }
          if((x = par[x]) == 0){
            break;
          }
        }
        cout << ans << "\n";
      }
    }
  }
}
namespace sub356{
  int par[lim_n], val[lim_n][lim_d];
  void dfs(int s){
    for(int& d : g[s]){
      if(d != par[s]){
        par[d] = s;
        dfs(d);
      }
    }
  }
  void solve(){
    for(int i = 1; i <= n; i++){
      fill(val[i], val[i] + lim_d, 1);
    }
    dfs(1);
    for(int i = 1; i <= q; i++){
      auto& [x, d, w] = query[i];
      if(d != -1){
        for(int i = 0; i <= d; i++){
          mul_mod(val[x][d - i], w);
          if((x = par[x]) == 0){
            break;
          }
        }
      }
      else{
        int ans = a[x];
        for(int i = 0; i < lim_d; i++){
          if(par[x] == 0){
            for(int j = i; j < lim_d; j++){
              mul_mod(ans, val[x][j]);
            }
            break;
          }
          else{
            mul_mod(ans, val[x][i]);
            if(i + 1 < lim_d){
              mul_mod(ans, val[x][i + 1]);
            }
            x = par[x];
          }
        }
        cout << ans << "\n";
      }
    }
  }
}
int main(){
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	if(fopen(taskname".inp", "r")){
		freopen(taskname".inp", "r", stdin);
	}
  cin >> n >> mod;
  for(int i = 1; i < n; i++){
    int u, v;
    cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  for(int i = 1; i <= n; i++){
    cin >> a[i];
  }
  cin >> q;
  for(int i = 1; i <= q; i++){
    int type;
    cin >> type;
    if(type == 1){
      cin >> query[i].x >> query[i].d >> query[i].w;
    }
    else{
      cin >> query[i].x;
      query[i].d = query[i].w = -1;
    }
  }
  if(max(n, q) <= 1000){
    sub1::solve();
  }
  else if(sub2::check_subtask()){
    sub2::solve();
  }
  else if(sub4::check_subtask()){
    sub4::solve();
  }
  else{
    sub356::solve();
  }
}

Compilation message (stderr)

sprinkler.cpp: In function 'int main()':
sprinkler.cpp:236:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  236 |                 freopen(taskname".inp", "r", stdin);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...