傳送門
題解:
很顯然的長鏈剖分。
合併顯然是一個取max。
詢問顯然是一個區間詢問max。
先長鏈剖分,搞出重兒子優先的dfs序,然後上線段樹就行了。
發現只有單點修改,區間詢問max,直接上ZKW線段樹。
跑得比香港記者還快
代碼:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define gc get_char
#define cs const
namespace IO{
inline char get_char(){
static cs int Rlen=1<<22|1;
static char buf[Rlen],*p1,*p2;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}
template<typename T>
inline T get(){
char c;T num;
while(!isdigit(c=gc()));num=c^48;
while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
return num;
}
inline int gi(){return get<int>();}
}
using namespace IO;
using std::cerr;
using std::cout;
cs int mod=998244353;
inline int add(int a,int b){a+=b-mod;return a+(a>>31&mod);}
inline int dec(int a,int b){a-=b;return a+(a>>31&mod);}
inline int mul(int a,int b){ll r=(ll)a*b;return r>=mod?r%mod:r;}
inline int power(int a,int b,int res=1){
for(;b;b>>=1,a=mul(a,a))(b&1)&&(res=mul(res,a));
return res;
}
inline void Inc(int &a,int b){a+=b-mod;a+=a>>31&mod;}
inline void Dec(int &a,int b){a-=b;a+=a>>31&mod;}
inline void Mul(int &a,int b){a=mul(a,b);}
template<class T>
inline void ckmax(T &a,T b){a<b?a=b:0;}
cs int N=1e6+7;
int n;
int pw[N];
inline void init_pw(){
pw[0]=1;for(int re i=1;i<=n;++i)pw[i]=mul(pw[i-1],23333);
}
int el[N],nxt[N],to[N],ecnt;
inline void adde(int u,int v){
nxt[++ecnt]=el[u],el[u]=ecnt,to[ecnt]=v;
}
int fa[N];
int L[N],R[N];
ll val[N],dis[N],ans[N];
int son[N],mxd[N];
void dfs1(int u,int p){
for(int re e=el[u],v=to[e];e;v=to[e=nxt[e]]){
dis[v]=dis[u]+val[v];dfs1(v,u);
if(mxd[v]+1>mxd[u]){
mxd[u]=mxd[v]+1;
son[u]=v;
}
}
}
int in[N],pos[N],clk;
void dfs2(int u,int p){
pos[in[u]=++clk]=u;
if(son[u])dfs2(son[u],u);
for(int re e=el[u],v=to[e];e;v=to[e=nxt[e]])if(v!=son[u])dfs2(v,u);
}
namespace SGT{
cs int N=1<<21|7;
ll mx[N];int M;
inline void build(int n){
for(M=1;M<=n+1;M<<=1);
for(int re i=M+1;i<=M+n;++i)mx[i]=dis[pos[i-M]];
for(int re i=M-1;i;--i)mx[i]=std::max(mx[i<<1],mx[i<<1|1]);
}
inline void cmax(int p,int p2){
p+=M,p2+=M;if(mx[p]>=mx[p2])return ;mx[p]=mx[p2];
for(p>>=1;p;p>>=1)mx[p]=std::max(mx[p<<1],mx[p<<1|1]);
}
inline ll query(int p){return mx[p+M];}
inline ll query(int l,int r){
ll ans=0;
for(l+=M-1,r+=M+1;l^r^1;l>>=1,r>>=1){
if(l&1^1)ckmax(ans,mx[l^1]);
if(r&1) ckmax(ans,mx[r^1]);
}
return ans;
}
}
void dfs3(int u,int p){
ans[u]=-1;
if(!son[u]){return ;}
dfs3(son[u],u);
if(L[u]<=mxd[u])ans[u]=SGT::query(in[u]+L[u],in[u]+std::min(mxd[u],R[u]))-dis[u];
for(int re e=el[u],v=to[e];e;v=to[e=nxt[e]])if(v!=son[u]){
dfs3(v,u);--in[v],++mxd[v];
for(int re i=1;i<=mxd[v];++i){
if(L[u]<=i&&i<=R[u])ckmax(ans[u],SGT::query(in[v]+i)-dis[u]);
int l=std::max(1,L[u]-i);
int r=std::min(mxd[u],R[u]-i);
if(l>r)continue;
ckmax(ans[u],SGT::query(in[v]+i)+SGT::query(in[u]+l,in[u]+r)-dis[u]*2);
}
for(int re i=1;i<=mxd[v];++i)SGT::cmax(in[u]+i,in[v]+i);
}
}
signed main(){
#ifdef zxyoi
freopen("watchdog.in","r",stdin);
#else
#ifndef ONLINE_JUDGE
freopen("watchdog.in","r",stdin);freopen("watchdog.out","w",stdout);
#endif
#endif
n=gi();init_pw();
for(int re i=1;i<=n;++i)L[i]=gi(),R[i]=gi();
for(int re i=2;i<=n;++i){
adde(fa[i]=gi(),i);
val[i]=gi();
}
dfs1(1,0);dfs2(1,0);SGT::build(n);
dfs3(1,0);int res=0;
for(int re i=1;i<=n;++i){
int t=ans[i]==-1?mod-1ll:(ans[i]%mod);
// cerr<<"i : "<<i<<" "<<ans[i]<<"\n";
Inc(res,mul(t,pw[n-i]));
}
cout<<res<<"\n";
return 0;
}