結果
| 問題 | No.650 行列木クエリ |
| コンテスト | |
| ユーザー |
ふぃぼん
|
| 提出日時 | 2026-10-03 16:37:15 |
| 言語 | C++23(gnu拡張) (gcc 15.3.0 + boost 1.92.0 + ACL) |
| 結果 |
AC
不安定
|
| 実行時間 | 415 ms / 2,000 ms |
| + 0µs | |
| コード長 | 4,479 bytes |
| 記録 | |
| コンパイル時間 | 5,813 ms |
| コンパイル使用メモリ | 403,632 KB |
| 実行使用メモリ | 115,956 KB |
| 最終ジャッジ日時 | 2026-10-03 16:37:37 |
| 合計ジャッジ時間 | 9,398 ms |
|
ジャッジサーバーID (参考情報) |
judge3_0 / judge4_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 10 |
ソースコード
#if __has_include(<acl_bits.hpp>)
#include <acl_bits.hpp>
#else
#include <bits/stdc++.h>
#include <atcoder/all>
#endif
using namespace atcoder;
using namespace std;
using ll=long long;
using ld=long double;
using P = pair<ll,ll>;
using TUP = tuple<ll,ll,ll>;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define drep(i,n) for (int i = (n-1); i >= 0; --i)
template<typename t,typename u>inline bool chmax(t&a,u b){return a<b?a=b,1:0;}
template<typename t,typename u>inline bool chmin(t&a,u b){return a>b?a=b,1:0;}
inline int yn(bool b){cout<<(b?"Yes\n":"No\n");return 0;}
const vector<int> di={1,0,-1,0},dj={0,1,0,-1};
using mint = modint1000000007;
inline ostream&operator<<(ostream&os,const mint& x){os<<x.val();return os;};
template <typename t>ostream&operator<<(ostream&os,const vector<t>&x){for(t i:x)os<<i<<' ';return os;}
template <typename t>ostream&operator<<(ostream&os,const vector<vector<t>>&x){for(const vector<t>&i:x)os<<i<<'\n';return os;}
const ll inf=2e18;
struct hld{
int n;
vector<int> vertex,id,head,par,dep;
hld(vector<vector<int>> g){
n=g.size();
id.resize(n);
head.resize(n);
par.resize(n);
dep.resize(n);
{
auto f=[&](auto f,int x,int px)->int{
int cnt=1,mx=0;
rep(i,g[x].size()){
int nx=g[x][i];
if(nx==px)continue;
int s=f(f,nx,x);
cnt+=s;
if(chmax(mx,s))swap(g[x][0],g[x][i]);
}
return cnt;
};
f(f,0,0);
}
{
auto f=[&](auto f,int x,int px)->void{
id[x]=vertex.size();
vertex.push_back(x);
for(int nx:g[x])if(px!=nx){
par[nx]=x;
dep[nx]=dep[x]+1;
head[nx]=(nx==g[x][0]?head[x]:nx);
f(f,nx,x);
}
};
f(f,0,0);
}
}
int lca(int u,int v){
while(head[u]!=head[v]){
if(id[u]>id[v])u=par[head[u]];
else v=par[head[v]];
}
return id[u]<id[v]?u:v;
}
int dist(int u,int v){
int c=lca(u,v);
return dep[u]+dep[v]-2*dep[c];
}
int level_ancestor(int u,int d){
if(dep[u]<d)return -1;
while(dep[head[u]]>d){
u=par[head[u]];
}
return vertex[id[u]-(dep[u]-d)];
}
int jump_up(int u,int steps){
return level_ancestor(u,dep[u]-steps);
}
int jump(int u,int v,int steps){
int c=lca(u,v);
int uc=dep[u]-dep[c];
int vc=dep[v]-dep[c];
if(steps < uc)return jump_up(u,steps);
else if(steps-uc<=vc)return jump_up(v,uc+vc-steps);
else return -1;
}
template<typename F,typename G>
void foreach(int u,int v,const F& f_uc,const G& f_vc){
stack<pair<int,int>> st;
while(head[u]!=head[v]){
if(id[u]>id[v]){
f_uc(id[head[u]],id[u]+1);
u=par[head[u]];
}else{
f_vc(id[head[v]],id[v]+1);
v=par[head[v]];
}
}
if(id[u]<id[v])f_vc(id[u],id[v]+1);
else f_uc(id[v],id[u]+1);
}
template<typename F,typename G>
void foreach_edge(int u,int v,const F& f_uc,const G& f_vc){
stack<pair<int,int>> st;
while(head[u]!=head[v]){
if(id[u]>id[v]){
f_uc(id[head[u]],id[u]+1);
u=par[head[u]];
}else{
f_vc(id[head[v]],id[v]+1);
v=par[head[v]];
}
}
if(id[u]<id[v])f_vc(id[u]+1,id[v]+1);
else f_uc(id[v]+1,id[u]+1);
}
template<typename F>
void foreach(int u,int v,const F& f){
foreach(u,v,f,f);
}
template<typename F>
void foreach_edge(int u,int v,const F& f){
foreach_edge(u,v,f,f);
}
};
template<typename T> vector<vector<T>> mat_mul(const vector<vector<T>>& a,const vector<vector<T>>& b){
if(a[0].size()!=b.size())return vector(a.size(),vector<T>(b[0].size()));
vector res(a.size(),vector<T>(b[0].size()));
rep(i,a.size())rep(j,b[0].size())rep(k,b.size()){
res[i][j]+=a[i][k]*b[k][j];
}
return res;
}
using S=vector<vector<mint>>;
S op1(S a,S b){return mat_mul(a,b);}
S op2(S a,S b){return mat_mul(b,a);}
S e(){return {{1,0},{0,1}};}
int main(){
int n;
cin>>n;
vector<vector<int>> g(n);
vector<P> es;
rep(i,n-1){
int u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
es.emplace_back(u,v);
}
hld hl(g);
segtree<S,op1,e> seg1(n);
segtree<S,op2,e> seg2(n);
int q;
cin>>q;
rep(qi,q){
char t;
cin>>t;
if(t=='x'){
int i;
cin>>i;
vector x(2,vector<mint>(2));
rep(ii,2)rep(j,2){
int tmp;
cin>>tmp;
x[ii][j]=tmp;
}
auto[u,v]=es[i];
int c=hl.id[u==hl.lca(u,v)?v:u];
seg1.set(c,x);
seg2.set(c,x);
}else{
int i,j;
cin>>i>>j;
S ls=e(),rs=e();
hl.foreach_edge(i,j,[&](int l,int r){
ls=mat_mul(ls,seg2.prod(l,r));
},[&](int l,int r){
rs=mat_mul(seg1.prod(l,r),rs);
});
S ans=mat_mul(ls,rs);
cout<<ans[0]<<ans[1]<<endl;
}
}
}
ふぃぼん