zoukankan      html  css  js  c++  java
  • BSOJ3392【省选模拟】树上的询问

    题目

    BSOJ3392【省选模拟】树上的询问

    分析

    点分治。

    点分治入门题,首先这题可以直接做,也可以转化成 "小于等于 (k) 的减掉 小于等于 (k-1) 的" ,然后相减来做。

    两者皆可。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    inline int inc(int x,int v,int mod){x+=v;return x>=mod?x-mod:x;}
    inline int dec(int x,int v,int mod){x-=v;return x<0?x+mod:x;}
    inline int read(){int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
    inline void write(int x){if(x==0){putchar(48);return;}int len=0,dg[20];while(x>0){dg[++len]=x%10;x/=10;}for(register int i=len;i>=1;i--)putchar(dg[i]+48);}
    const int N=1e5+5;
    const int M=1e7+5;
    struct node{
        int to,next,val;
    }edge[1000005];
    int used[N],head[N],idy,q[N],maxson[N],tot,size[N],dis[N],rev[N],cnt;
    bool vis[N],ans[N],rvis[M];
    int n,m,id,idx;
    void add(int u,int v,int w){
        edge[++idx].to=v;
        edge[idx].next=head[u];
        edge[idx].val=w;
        head[u]=idx;
        return ;
    }
    void dfs(int x,int fa){ 
    	size[x]=1;
    	maxson[x]=0;
    	for(int i=head[x];i;i=edge[i].next){
    		int y=edge[i].to;
    		if(y==fa||vis[y])continue;
    		dfs(y,x);
    		size[x]+=size[y];
    		maxson[x]=max(maxson[x],size[y]);
    	}
    	maxson[x]=max(maxson[x],tot-size[x]);
    	if(maxson[x]<maxson[id])id=x;
    	return ;
    }
    void dist(int x,int fa){
    	rev[++cnt]=dis[x];
    	for(int i=head[x];i;i=edge[i].next){
    		int y=edge[i].to;
    		if(y==fa||vis[y])continue;
    		dis[y]=dis[x]+edge[i].val;
    		dist(y,x);
    	}
    }
    void calc(int x){
    	idy=0;
    	for(int i=head[x];i;i=edge[i].next){
    		int y=edge[i].to;
    		if(vis[y])continue;
    		cnt=0;
    		dis[y]=edge[i].val;
    		dist(y,x);
    		for(int j=1;j<=cnt;j++){
    			for(int k=1;k<=m;k++){
    				if(q[k]-rev[j]>=0&&q[k]-rev[j]<=1e7 && rvis[q[k]-rev[j]])ans[k]=1;
    			}
    		}
    		for(int j=1;j<=cnt;j++) if(rev[j]<=1e7)used[++idy]=rev[j],rvis[rev[j]]=1;
    	}
    	for(int i=1;i<=idy;i++)rvis[used[i]]=0;
    }
    void solve(int x){
    	vis[x]=rvis[0]=1;
    	calc(x);
    	for(int i=head[x];i;i=edge[i].next){
    	    int y=edge[i].to;
    		if(vis[y])continue;
    		id=0;
    		maxson[id]=tot=size[y];
    		dfs(y,0);
    		solve(id);
    	}
    }
    int main(){
        n=read(),m=read();
        for(int i=1;i<=n-1;i++){
            int x=read(),y=read(),z=read();
            add(x,y,z),add(y,x,z);
        }
    	for(int i=1;i<=m;i++)q[i]=read();
        maxson[id]=tot=n;
        dfs(1,0);
        solve(id);
        for(int i=1;i<=m;i++){
        	printf("%s
    ",(ans[i]||(!q[i])) ? "Yes" : "No");
    	}
    	return 0;
    }
    

    感受

    这题第二种做法很巧妙,同样的办法在一道模拟题也见过,同样是容斥,但是那道题是 (dp)

  • 相关阅读:
    Asp.NET 4.0 ajax实例DataView 模板编程1
    ASP.NET 4.0 Ajax 实例DataView模板编程 DEMO 下载
    部分东北话、北京话
    .NET 培训课程解析(一)
    ASP.NET 4.0 Ajax 实例DataView模板编程2
    ASP.NET Web Game 架构设计1服务器基本结构
    ASP.NET Web Game 构架设计2数据库设计
    TFS2008 基本安装
    Linux上Oracle 11g安装步骤图解
    plsql developer远程连接oracle数据库
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14738567.html
Copyright © 2011-2022 走看看