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);
		}
	}
}

猜你喜欢

转载自www.cnblogs.com/kalginamiemeng/p/Exam20191019.html
19