19-10-19-I
中午考试困够呛。
T1
我想打矩阵快速幂,然后我咕了
T2
打T1了所以又咕了。
T3
每一个黑点更新答案只有两种方式:
- 更新子树。
- 更新父链上的兄弟,叔伯,……
于是:
把树拍在$DFS$序上。
更新子树,区间修改。
更新父链,就需要用$DFS$序的拆分,修改两个部分。
#include <iostream>
#include <cstring>
#include <cstdio>
#define N 111111
#define lc(k) (k<<1)
#define rc(k) (k<<1|1)
using namespace std;
struct SR{
int next,t;
}rs[N*2];
int fl[N],cnt=0;
struct XDS{
int l,r;
int dat,lz;
}rt[4*N];
int fir[N],las[N],wi[N];
int dfsxu[2*N];
int dfcnt=0;
int fa[N],pn,qn;
bool is_v[N];
void add(int f,int t){
rs[cnt].t=t;
rs[cnt].next=fl[f];
fl[f]=cnt++;
}
void build(int k,int l,int r){
// cout<<k<<" "<<l<<" "<<r<<endl;
rt[k].l=l,rt[k].r=r;
rt[k].dat=0;
if(l==r)return ;
int mid=(l+r)/2;
build(lc(k),l ,mid);
build(rc(k),mid+1,r );
}
void downlz(int k){
if(rt[k].l!=rt[k].r && rt[k].lz!=0){
int val=rt[k].lz;
rt[lc(k)].lz=max(rt[lc(k)].lz,val);
rt[rc(k)].lz=max(rt[rc(k)].lz,val);
rt[lc(k)].dat=max(rt[lc(k)].dat,val);
rt[rc(k)].dat=max(rt[rc(k)].dat,val);
rt[k].lz=0;
}
}
void change(int k,int l,int r,int v){
if(l>r)return ;
downlz(k);
if(l<=rt[k].l && rt[k].r<=r){
rt[k].lz=v;
rt[k].dat=max(rt[k].dat,v);
return ;
}
int mid=(rt[k].l+rt[k].r)/2;
if(mid>=l)
change(lc(k),l,r,v);
if(mid<r)
change(rc(k),l,r,v);
rt[k].dat=max(rt[lc(k)].dat,rt[rc(k)].dat);
}
int query(int k,int l,int r){
if(l>r)return 0;
int ans=0;
downlz(k);
if(l<=rt[k].l && rt[k].r<=r)
return rt[k].dat;
int mid=(rt[k].l+rt[k].r)/2;
if(mid>=l)
ans=max(ans,query(lc(k),l,r));
if(mid<r)
ans=max(ans,query(rc(k),l,r));
return ans;
}
void dfs(int k,int pre){
dfcnt++;
dfsxu[dfcnt]=k;
fir[k]=dfcnt;
for(int i=fl[k];i!=-1;i=rs[i].next){
int t=rs[i].t;
if(t!=pre){
fa[t]=k;
dfs(t,k);
}
}
dfcnt++;
dfsxu[dfcnt]=k;
las[k]=dfcnt;
}
int main(){
// freopen("lca3.in","r",stdin);\
freopen("1.out","w",stdout);
int a,b;
char st[10];
memset(fl,-1,sizeof fl);
scanf("%d%d",&pn,&qn);
for(int i=1;i<=pn;i++)
scanf("%d",wi+i);
for(int i=1;i<pn;i++){
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
dfs(1,0);
// for(int i=1;i<=pn*2;i++)\
cout<<dfsxu[i]<<" ";\
cout<<endl;
build(1,1,pn*2);
for(int i=1;i<=qn;i++){
scanf("%s%d",st,&a);
if(st[0]=='M'){
change(1,fir[a],las[a],wi[a]);
// cout<<fir[a]<<"="<<las[a]<<endl;
while(fa[a]!=0){
// cout<<"A:"<<a<<" FAA:"<<fa[a]<<" wi:"<<wi[fa[a]]<<endl;
change(1,fir[fa[a]],fir[a]-1,wi[fa[a]]);
// cout<<fir[fa[a]]<<" "<<fir[a]-1<<endl;
change(1,las[a]+1,las[fa[a]],wi[fa[a]]);
// cout<<las[a]+1<<" "<<las[fa[a]]-1<<endl;
if(is_v[a])break;
is_v[a]=1;
a=fa[a];
}
}
else {
int ans=query(1,fir[a],fir[a]);
printf("%d\n",ans==0?-1:ans);
}
}
}
Miemeng真的蒻

浙公网安备 33010602011771号