• 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
    ",ans==0?-1:ans);
    		}
    	}
    }
    
  • 相关阅读:
    CF 793 B (队列中的交换位置)
    WPF转换器
    WPF自定义控件指针仪表(依赖属性)
    面试可能会问到的问题
    返回局部变量是一个指向常量的字符串指针
    自定义c++二维动态数组
    1. 文件乱码 行远
    Nginx自启动脚本
    实验一密码引擎商用密码算法实现2交叉测试
    ARC117F Gateau
  • 原文地址:https://www.cnblogs.com/kalginamiemeng/p/Exam20191019.html
Copyright © 2020-2023  润新知