結果
問題 | No.2470 Gemini Tree(Ver.Jadeite) |
ユーザー |
👑 ![]() |
提出日時 | 2023-07-29 06:42:16 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 435 ms / 5,000 ms |
コード長 | 15,058 bytes |
コンパイル時間 | 2,728 ms |
コンパイル使用メモリ | 225,572 KB |
最終ジャッジ日時 | 2025-02-15 20:54:18 |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 27 |
ソースコード
//#define _GLIBCXX_DEBUG//#pragma GCC target("avx2")//#pragma GCC optimize("O3")//#pragma GCC optimize("unroll-loops")#include<bits/stdc++.h>using namespace std;#ifdef LOCAL#include <debug_print.hpp>#define OUT(...) debug_print::multi_print(#__VA_ARGS__, __VA_ARGS__)#else#define OUT(...) (static_cast<void>(0))#endif#define endl '\n'#define lfs cout<<fixed<<setprecision(15)#define ALL(a) (a).begin(),(a).end()#define ALLR(a) (a).rbegin(),(a).rend()#define UNIQUE(a) (a).erase(unique((a).begin(),(a).end()),(a).end())#define spa << " " <<#define fi first#define se second#define MP make_pair#define MT make_tuple#define PB push_back#define EB emplace_back#define rep(i,n,m) for(ll i = (n); i < (ll)(m); i++)#define rrep(i,n,m) for(ll i = (ll)(m) - 1; i >= (ll)(n); i--)using ll = long long;using ld = long double;const ll MOD1 = 1e9+7;const ll MOD9 = 998244353;const ll INF = 1e18;using P = pair<ll, ll>;template<typename T> using PQ = priority_queue<T>;template<typename T> using QP = priority_queue<T,vector<T>,greater<T>>;template<typename T1, typename T2>bool chmin(T1 &a,T2 b){if(a>b){a=b;return true;}else return false;}template<typename T1, typename T2>bool chmax(T1 &a,T2 b){if(a<b){a=b;return true;}else return false;}ll median(ll a,ll b, ll c){return a+b+c-max({a,b,c})-min({a,b,c});}void ans1(bool x){if(x) cout<<"Yes"<<endl;else cout<<"No"<<endl;}void ans2(bool x){if(x) cout<<"YES"<<endl;else cout<<"NO"<<endl;}void ans3(bool x){if(x) cout<<"Yay!"<<endl;else cout<<":("<<endl;}template<typename T1,typename T2>void ans(bool x,T1 y,T2 z){if(x)cout<<y<<endl;else cout<<z<<endl;}template<typename T1,typename T2,typename T3>void anss(T1 x,T2 y,T3 z){ans(x!=y,x,z);};template<typename T>void debug(const T &v,ll h,ll w,string sv=" "){for(ll i=0;i<h;i++){cout<<v[i][0];for(ll j=1;j<w;j++)cout<<sv<<v[i][j];cout<<endl;}};template<typename T>void debug(const T &v,ll n,string sv=" "){if(n!=0)cout<<v[0];for(ll i=1;i<n;i++)cout<<sv<<v[i];cout<<endl;};template<typename T>void debug(const vector<T>&v){debug(v,v.size());}template<typename T>void debug(const vector<vector<T>>&v){for(auto &vv:v)debug(vv,vv.size());}template<typename T>void debug(stack<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}template<typename T>void debug(queue<T> st){while(!st.empty()){cout<<st.front()<<" ";st.pop();}cout<<endl;}template<typename T>void debug(deque<T> st){while(!st.empty()){cout<<st.front()<<" ";st.pop_front();}cout<<endl;}template<typename T>void debug(PQ<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}template<typename T>void debug(QP<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}template<typename T>void debug(const set<T>&v){for(auto z:v)cout<<z<<" ";cout<<endl;}template<typename T>void debug(const multiset<T>&v){for(auto z:v)cout<<z<<" ";cout<<endl;}template<typename T,size_t size>void debug(const array<T, size> &a){for(auto z:a)cout<<z<<" ";cout<<endl;}template<typename T,typename V>void debug(const map<T,V>&v){for(auto z:v)cout<<"["<<z.first<<"]="<<z.second<<",";cout<<endl;}template<typename T>vector<vector<T>>vec(ll x, ll y, T w){vector<vector<T>>v(x,vector<T>(y,w));return v;}ll gcd(ll x,ll y){ll r;while(y!=0&&(r=x%y)!=0){x=y;y=r;}return y==0?x:y;}vector<ll>dx={1,-1,0,0,1,1,-1,-1};vector<ll>dy={0,0,1,-1,1,-1,1,-1};template<typename T>vector<T> make_v(size_t a,T b){return vector<T>(a,b);}template<typename... Ts>auto make_v(size_t a,Ts... ts){return vector<decltype(make_v(ts...))>(a,make_v(ts...));}template<typename T1, typename T2>ostream &operator<<(ostream &os, const pair<T1, T2>&p){return os << "(" << p.first << "," << p.second << ")";}template<typename T>ostream &operator<<(ostream &os, const vector<T> &v){os<<"[";for(auto &z:v)os << z << ",";os<<"]"; return os;}template<typename T>void rearrange(vector<int>&ord, vector<T>&v){auto tmp = v;for(int i=0;i<tmp.size();i++)v[i] = tmp[ord[i]];}template<typename Head, typename... Tail>void rearrange(vector<int>&ord,Head&& head, Tail&&... tail){rearrange(ord, head);rearrange(ord, tail...);}template<typename T> vector<int> ascend(const vector<T>&v){vector<int>ord(v.size());iota(ord.begin(),ord.end(),0);sort(ord.begin(),ord.end(),[&](int i,int j){return make_pair(v[i],i)<make_pair(v[j],j);});return ord;}template<typename T> vector<int> descend(const vector<T>&v){vector<int>ord(v.size());iota(ord.begin(),ord.end(),0);sort(ord.begin(),ord.end(),[&](int i,int j){return make_pair(v[i],-i)>make_pair(v[j],-j);});return ord;}template<typename T> vector<T> inv_perm(const vector<T>&ord){vector<T>inv(ord.size());for(int i=0;i<ord.size();i++)inv[ord[i]] = i;return inv;}ll FLOOR(ll n,ll div){assert(div>0);return n>=0?n/div:(n-div+1)/div;}ll CEIL(ll n,ll div){assert(div>0);return n>=0?(n+div-1)/div:n/div;}ll digitsum(ll n){ll ret=0;while(n){ret+=n%10;n/=10;}return ret;}ll modulo(ll n,ll d){return (n%d+d)%d;};template<typename T>T min(const vector<T>&v){return *min_element(v.begin(),v.end());}template<typename T>T max(const vector<T>&v){return *max_element(v.begin(),v.end());}template<typename T>T acc(const vector<T>&v){return accumulate(v.begin(),v.end(),T(0));};template<typename T>T reverse(const T &v){return T(v.rbegin(),v.rend());};//mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());int popcount(ll x){return __builtin_popcountll(x);};int poplow(ll x){return __builtin_ctzll(x);};int pophigh(ll x){return 63 - __builtin_clzll(x);};template<typename T>T poll(queue<T> &q){auto ret=q.front();q.pop();return ret;};template<typename T>T poll(priority_queue<T> &q){auto ret=q.top();q.pop();return ret;};template<typename T>T poll(QP<T> &q){auto ret=q.top();q.pop();return ret;};template<typename T>T poll(stack<T> &s){auto ret=s.top();s.pop();return ret;};ll MULT(ll x,ll y){if(LLONG_MAX/x<=y)return LLONG_MAX;return x*y;}ll POW2(ll x, ll k){ll ret=1,mul=x;while(k){if(mul==LLONG_MAX)return LLONG_MAX;if(k&1)ret=MULT(ret,mul);mul=MULT(mul,mul);k>>=1;}return ret;}ll POW(ll x, ll k){ll ret=1;for(int i=0;i<k;i++){if(LLONG_MAX/x<=ret)return LLONG_MAX;ret*=x;}return ret;}namespace converter{int dict[500];const string lower="abcdefghijklmnopqrstuvwxyz";const string upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ";const string digit="0123456789";const string digit1="123456789";void regi_str(const string &t){for(int i=0;i<t.size();i++){dict[t[i]]=i;}}void regi_int(const string &t){for(int i=0;i<t.size();i++){dict[i]=t[i];}}vector<int>to_int(const string &s,const string &t){regi_str(t);vector<int>ret(s.size());for(int i=0;i<s.size();i++){ret[i]=dict[s[i]];}return ret;}vector<int>to_int(const string &s){auto t=s;sort(t.begin(),t.end());t.erase(unique(t.begin(),t.end()),t.end());return to_int(s,t);}vector<vector<int>>to_int(const vector<string>&s,const string &t){regi_str(t);vector<vector<int>>ret(s.size(),vector<int>(s[0].size()));for(int i=0;i<s.size();i++){for(int j=0;j<s[0].size();j++){ret[i][j]=dict[s[i][j]];}}return ret;}vector<vector<int>>to_int(const vector<string>&s){string t;for(int i=0;i<s.size();i++){t+=s[i];}sort(t.begin(),t.end());t.erase(unique(t.begin(),t.end()),t.end());return to_int(s,t);}string to_str(const vector<int>&s,const string &t){regi_int(t);string ret;for(auto z:s)ret+=dict[z];return ret;}vector<string> to_str(const vector<vector<int>>&s,const string &t){regi_int(t);vector<string>ret(s.size());for(int i=0;i<s.size();i++){for(auto z:s[i])ret[i]+=dict[z];}return ret;}}template< typename T = int >struct edge {int to;T cost;int id;edge():to(-1),id(-1){};edge(int to, T cost = 1, int id = -1):to(to), cost(cost), id(id){}operator int() const { return to; }};template<typename T>using Graph = vector<vector<edge<T>>>;template<typename T>Graph<T>revgraph(const Graph<T> &g){Graph<T>ret(g.size());for(int i=0;i<g.size();i++){for(auto e:g[i]){int to = e.to;e.to = i;ret[to].push_back(e);}}return ret;}template<typename T>Graph<T> readGraph(int n,int m,int indexed=1,bool directed=false,bool weighted=false){Graph<T> ret(n);for(int es = 0; es < m; es++){int u,v;T w=1;cin>>u>>v;u-=indexed,v-=indexed;if(weighted)cin>>w;ret[u].emplace_back(v,w,es);if(!directed)ret[v].emplace_back(u,w,es);}return ret;}template<typename T>Graph<T> readParent(int n,int indexed=1,bool directed=true){Graph<T>ret(n);for(int i=1;i<n;i++){int p;cin>>p;p-=indexed;ret[p].emplace_back(i);if(!directed)ret[i].emplace_back(p);}return ret;}template<typename T>pair<vector<int>,vector<int>>inout(const Graph<T>&g,int root=-1) {vector<int>in(g.size(),-1),out(g.size(),-1);int time=0;auto dfs=[&](auto &&self,int k)->void {in[k]=time++;for(auto to:g[k]){if(in[to]!=-1)continue;self(self,to);}out[k]=time;};if(root==-1){for(int i=0;i<g.size();i++){if(in[i]==-1)dfs(dfs,i);}}else dfs(dfs,root);return make_pair(move(in),move(out));}template< typename Monoid, typename OperatorMonoid,typename F, typename G, typename H>struct LazySegmentTree {ll sz, height, n;vector< Monoid > data;vector< OperatorMonoid > lazy;const F f;const G g;const H h;Monoid M1;OperatorMonoid OM0;LazySegmentTree(int n, const F &f,const G &g, const H &h, Monoid M1, OperatorMonoid OM0):n(n),f(f),g(g),h(h),M1(M1),OM0(OM0){sz = 1;height = 0;while(sz < n) sz <<= 1, height++;data.assign(2 * sz, M1);lazy.assign(2 * sz, OM0);}void set(ll k, const Monoid &x) {data[k + sz] = x;}void build() {for(ll k = sz - 1; k > 0; k--) {data[k] = f(data[2 * k + 0], data[2 * k + 1]);}}inline void propagate(int k) {if(lazy[k] != OM0) {lazy[2 * k + 0] = h(lazy[2 * k + 0], lazy[k]);lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);data[k] = reflect(k);lazy[k] = OM0;}}inline Monoid reflect(int k) {return lazy[k] == OM0 ? data[k] : g(data[k], lazy[k]);}inline void recalc(int k) {while(k >>= 1) data[k] = f(reflect(2 * k + 0), reflect(2 * k + 1));}inline void thrust(int k) {for(ll i = height; i > 0; i--) propagate(k >> i);}void update(int a, int b, const OperatorMonoid &x) {if(a>=b)return;thrust(a += sz);thrust(b += sz - 1);for(ll l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {if(l & 1) lazy[l] = h(lazy[l], x), ++l;if(r & 1) --r, lazy[r] = h(lazy[r], x);}recalc(a);recalc(b);}void update(int a,const Monoid &x){thrust(a += sz);data[a] = x;lazy[a] = OM0;recalc(a);}Monoid query(int a, int b) {if(a>=b)return M1;thrust(a += sz);thrust(b += sz - 1);Monoid L = M1, R = M1;for(ll l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {if(l & 1) L = f(L, reflect(l++));if(r & 1) R = f(reflect(--r), R);}return f(L, R);}Monoid operator[](const int &k) {return query(k, k + 1);}Monoid all_prod(){return reflect(1);}template< typename C >ll find_subtree(int a, const C &check, Monoid &M, bool type) {while(a < sz) {propagate(a);Monoid nxt = type ? f(reflect(2 * a + type), M) : f(M, reflect(2 * a + type));if(check(nxt)) a = 2 * a + type;else M = nxt, a = 2 * a + 1 - type;}return a - sz;}template< typename C >ll find_first(int a, const C &check) {Monoid L = M1;if(a <= 0) {if(check(f(L, reflect(1)))) return find_subtree(1, check, L, false);return n;}thrust(a + sz);ll b = sz;for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {if(a & 1) {Monoid nxt = f(L, reflect(a));if(check(nxt)) return find_subtree(a, check, L, false);L = nxt;++a;}}return n;}template< typename C >ll find_last(int b, const C &check) {Monoid R = M1;if(b >= sz) {if(check(f(reflect(1), R))) return find_subtree(1, check, R, true);return -1;}thrust(b + sz - 1);ll a = sz;for(b += sz; a < b; a >>= 1, b >>= 1) {if(b & 1) {Monoid nxt = f(reflect(--b), R);if(check(nxt)) return find_subtree(b, check, R, true);R = nxt;}}return -1;}void print(){for(ll i=0;i<n;i++)if((*this)[i]==M1)cout<<"x|";else cout<<(*this)[i]<<"|";cout<<endl;}};namespace add_min{using M=ll;auto f=[](M x,M y){return min(x,y);};auto g=[](M x,M y){return x + y;};auto h=[](M x,M y){return x + y;};LazySegmentTree<M,M,decltype(f),decltype(g),decltype(h)>make(int n){return {n,f,g,h,INF,0};}}int main(){cin.tie(nullptr);ios_base::sync_with_stdio(false);ll res=0,buf=0;bool judge = true;ll n;cin>>n;string s;cin>>s;vector<ll>u(n-1),v(n-1),w(n-1);rep(i,0,n-1)cin>>u[i]>>v[i]>>w[i],u[i]--,v[i]--;Graph<ll>g(n);rep(i,0,n-1){g[u[i]].EB(v[i],w[i]);g[v[i]].EB(u[i],w[i]);}string GB="GB";ll q;cin>>q;vector<ll>e(q),a(q);rep(i,0,q){cin>>e[i]>>a[i];e[i]--;}vector<ll>ret(q,INF);for(auto c:GB){vector<ll>subc(n),subsz(n);auto [in,out]=inout(g);rep(i,0,n)if(in[u[i]]>in[v[i]])swap(u[i],v[i]);{auto dfs=[&](auto &&f,int k,int par)->void {subsz[k]++;if(s[k]==c)subc[k]++;for(auto to:g[k]){if(to==par)continue;f(f,to,k);subsz[k]+=subsz[to];subc[k]+=subc[to];}};dfs(dfs,0,-1);}ll cnt=subc[0];vector<ll>aff(n,-1);auto seg=add_min::make(n);rep(i,0,n)seg.set(i,INF/2);{int ai=0;auto dfs=[&](auto &&f,int k,int par)->void {if(cnt==subsz[k]){aff[k]=k;seg.set(in[k],0);}else if(par!=-1)aff[k]=aff[par];for(auto to:g[k]){if(to==par)continue;f(f,to,k);}};dfs(dfs,0,-1);}//OUT(cnt,subsz,subc);seg.build();auto add_cost=[&](ll ei,ll add){if(add==0)return;//下りコスト{ll need=min(subsz[v[ei]],cnt)-subc[v[ei]];ll pos=v[ei];if(aff[pos]!=-1)pos=aff[pos];seg.update(in[pos],out[pos],need*add);}//上りコスト{ll need=subc[v[ei]];ll pos=v[ei];if(aff[pos]!=-1)pos=aff[pos];seg.update(0,in[pos],need*add);seg.update(out[pos],n,need*add);}};rep(i,0,n-1)add_cost(i,w[i]);rep(i,0,q){add_cost(e[i],a[i]);//seg.print();chmin(ret[i],seg.all_prod());}}rep(i,0,q)cout<<ret[i]<<endl;return 0;}