• P3320 [SDOI2015]寻宝游戏


    题目

    P3320 [SDOI2015]寻宝游戏

    做法

    很巧妙的一种思路,懂了之后觉得大水题

    首先要知道:在一棵树上标记一些点,然后从任意一点出发,遍历所有的的最小路径为(dfs)序从小到大遍历

    那就把点丢到(set)里面,然后找(dfs)的前驱与后继计算路径就好了

    其实也有点虚树的思想,只管标记的这几个点

    My complete code

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<ctime>
    #include<vector>
    #include<cmath>
    #include<set>
    using namespace std;
    typedef long long LL;
    const LL maxn=1e5+9;
    inline LL Read(){
    	LL x(0),f(1);char c=getchar();
    	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    	while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
    	return x*f;
    }
    struct node{
    	LL to,next,d;
    }dis[maxn<<1];
    LL n,T,num,ans,tot;
    LL head[maxn],dfn[maxn],pos[maxn],inc[maxn][25],d[maxn],dep[maxn],visit[maxn];
    inline void Add(LL u,LL v,LL d){
    	dis[++num]=(node){v,head[u],d},head[u]=num;
    }
    void Dfs(LL u){
    	dfn[u]=++tot,pos[tot]=u;
    	for(LL i=1;i<=21;++i)
    	    inc[u][i]=inc[inc[u][i-1]][i-1];
    	for(LL i=head[u];i;i=dis[i].next){
    		LL v(dis[i].to);
    		if(v==inc[u][0])
    		    continue;
    		d[v]=d[u]+dis[i].d,inc[v][0]=u,dep[v]=dep[u]+1;
    		Dfs(v);
    	}
    }
    inline LL Lca(LL x,LL y){
    	if(dep[x]<dep[y])swap(x,y);
    	for(LL i=20;i>=0;--i)
    	    if(dep[inc[x][i]]>=dep[y])
    	        x=inc[x][i];
    	if(x==y)return x;
        for(LL i=20;i>=0;--i)
            if(inc[x][i]!=inc[y][i])
                x=inc[x][i],y=inc[y][i];
        return inc[x][0];
    }
    set<LL> Set;
    set<LL> :: iterator it,pre,next;
    inline void Query(LL x){
    	it=Set.find(dfn[x]);
    	if(it==Set.begin()){
    		pre=Set.end(),--pre;
    	}else{
    		pre=it,--pre;
    	}
    	next=it,++next;
    	if(next==Set.end())
    	    next=Set.begin();
    	it=Set.find(dfn[x]);
    }
    inline LL Change(){
    	return 2*d[pos[*it]]+d[pos[*next]]+d[pos[*pre]]-2*d[Lca(pos[*pre],pos[*it])]-2*d[Lca(pos[*next],pos[*it])];
    }
    inline LL Split(){
    	return d[pos[*pre]]+d[pos[*next]]-2*d[Lca(pos[*pre],pos[*next])];
    }
    int main(){
    	n=Read(),T=Read();
    	for(LL i=1;i<n;++i){
    		LL u(Read()),v(Read()),d(Read());
    	    Add(u,v,d),Add(v,u,d);
    	}
    	Dfs(1);
    	while(T--){
    		LL now(Read());
    		if(visit[now]){
    			Query(now),
    			ans-=Change(),ans+=Split(),
    			Set.erase(dfn[now]);
    		}else{
    			Set.insert(dfn[now]),
    			Query(now),
    			ans-=Split(),ans+=Change();
    		}
    		visit[now]^=1;
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }/*
    */
    
  • 相关阅读:
    Spring框架学习09——基于AspectJ的AOP开发
    Spring框架学习08——自动代理方式实现AOP
    Spring框架学习07——基于传统代理类的AOP实现
    Spring框架学习06——AOP底层实现原理
    Spring框架学习05——AOP相关术语详解
    SpringMVC框架09——@ResponseBody的用法详解
    Spring框架学习04——复杂类型的属性注入
    Spring框架学习03——Spring Bean 的详解
    Spring框架学习01——使用IDEA开发Spring程序
    sqlserver 迁移
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10295225.html
Copyright © 2020-2023  润新知