• CH6302 雨天的尾巴


    背景

    深绘里一直很讨厌雨天。
    灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切。
    虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒了几座老房子,几棵老树被连根拔起,以及田地里的粮食被弄得一片狼藉。
    无奈的深绘里和村民们只好等待救济粮来维生。
    不过救济粮的发放方式很特别。

    描述

    有 N (N≤10^5) 个点,形成一个树状结构。
    有 M (M≤10^5) 次发放操作,每次选择两个点 x,y,对 x 到 y 的路径上(包括 x,y)的每个点发放一袋 z (z≤10^9) 类型的物品。
    求完成所有发放操作后,每个点存放最多的是哪种类型的物品。

    输入格式

    第一行两个正整数n,m,含义如题目所示。
    接下来n-1行,每行两个数(a,b),表示(a,b)间有一条边。
    再接下来m行,每行三个数(x,y,z),含义如题目所示。

    输出格式

    n行,第i行一个整数,表示第i座房屋里存放的最多的是哪种救济粮,如果有多种救济粮存放次数一样,输出编号最小的。
    如果某座房屋里没有救济粮,则对应一行输出0。

    样例输入

    5 3
    1 2
    3 1
    3 4
    5 3
    2 3 3
    1 5 2
    3 3 3

    样例输出

    2
    3
    3
    0
    2

    数据范围与约定

    • 对于20%的数据,1 <= n, m <= 100
    • 对于50%的数据,1 <= n, m <= 2000
    • 对于100%的数据,1 <= n, m <= 100000, 1 <= a, b, x, y <= n, 1 <= z <= 100000

    来源

    Vani,Vani有约会杯邀请赛

            </article>
    

    题解

    可使用树上差分对物品计数,每个物品在x,y处+1,在lca,fa[lca]处-1即可。
    使用线段树合并解决空间问题。时间复杂度(O(nlog n))

    练习一下tarjan求lca。

    #include<bits/stdc++.h>
    #define rg register
    #define il inline
    #define co const
    template<class T>il T read(){
        rg T data=0,w=1;rg char ch=getchar();
        for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
        for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
        return data*w;
    }
    template<class T>il T read(rg T&x) {return x=read<T>();}
    typedef long long ll;
    using namespace std;
    
    co int N=1e5+1;
    int n,m;
    // tarjan lca
    vector<int> e[N];
    int x[N],y[N],z[N],val[N],cnt;
    vector<pair<int,int> > q[N];
    int vis[N],pa[N],lca[N],fa[N]; // pa for disjoint set,fa for real father
    int find(int x) {return pa[x]==x?x:pa[x]=find(pa[x]);}
    void tarjan(int x){
    	vis[x]=1;
    	for(int i=0,y;i<e[x].size();++i){
    		if(vis[y=e[x][i]]) continue;
    		tarjan(y);
    		pa[y]=fa[y]=x;
    	}
    	for(int i=0,y;i<q[x].size();++i)
    		if(vis[y=q[x][i].first]==2)
    			lca[q[x][i].second]=find(y);
    	vis[x]=2;
    }
    // Interval Tree
    int tot,lc[N*72],rc[N*72],dat[N*72],pos[N*72];
    void insert(int&x,int l,int r,int p,int d){
    	if(!x) x=++tot;
    	if(l==r){
    		dat[x]+=d,pos[x]=dat[x]?l:0;
    		return;
    	}
    	int mid=l+r>>1;
    	if(p<=mid) insert(lc[x],l,mid,p,d);
    	else insert(rc[x],mid+1,r,p,d);
    	if(dat[lc[x]]>=dat[rc[x]])
    		dat[x]=dat[lc[x]],pos[x]=pos[lc[x]];
    	else
    		dat[x]=dat[rc[x]],pos[x]=pos[rc[x]];
    }
    int merge(int x,int y,int l,int r){
    	if(!x||!y) return x+y;
    	if(l==r){
    		dat[x]+=dat[y],pos[x]=dat[x]?l:0;
    		return x;
    	}
    	int mid=l+r>>1; // edit 1: >>
    	lc[x]=merge(lc[x],lc[y],l,mid);
    	rc[x]=merge(rc[x],rc[y],mid+1,r);
    	if(dat[lc[x]]>=dat[rc[x]])
    		dat[x]=dat[lc[x]],pos[x]=pos[lc[x]];
    	else
    		dat[x]=dat[rc[x]],pos[x]=pos[rc[x]];
    	return x;
    }
    
    int root[N],ans[N];
    void dfs(int x){
    	for(int i=0,y;i<e[x].size();++i){
    		if((y=e[x][i])==fa[x]) continue;
    		dfs(y);
    		root[x]=merge(root[x],root[y],1,cnt);
    	}
    	ans[x]=pos[root[x]];
    }
    int main(){
    //	freopen("CH6302.in","r",stdin),freopen("CH6302.out","w",stdout);
    	read(n),read(m);
    	for(int i=1,x,y;i<n;++i){
    		read(x),read(y);
    		e[x].push_back(y),e[y].push_back(x);
    	}
    	for(int i=1;i<=m;++i){
    		read(x[i]),read(y[i]),val[i]=read(z[i]);
    		if(x[i]==y[i]) lca[i]=x[i];
    		else q[x[i]].push_back(make_pair(y[i],i)),q[y[i]].push_back(make_pair(x[i],i));
    	}
    	for(int i=1;i<=n;++i) pa[i]=i;
    	tarjan(1);
    	sort(val+1,val+m+1),cnt=unique(val+1,val+m+1)-val-1;
    	for(int i=1;i<=m;++i){
    		z[i]=lower_bound(val+1,val+cnt+1,z[i])-val;
    //		cerr<<i<<" lca="<<lca[i]<<endl;
    		insert(root[x[i]],1,cnt,z[i],1);
    		insert(root[y[i]],1,cnt,z[i],1);
    		insert(root[lca[i]],1,cnt,z[i],-1);
    		if(fa[lca[i]]) insert(root[fa[lca[i]]],1,cnt,z[i],-1);
    	}
    	dfs(1);
    	for(int i=1;i<=n;++i) printf("%d
    ",val[ans[i]]);
    	return 0;
    }
    
  • 相关阅读:
    mysql 5.7.28 中GROUP BY报错问题 SELECT list is not in GROUP BY clause and contains no
    mysql 的root 用户无法授权,navicat 远程授权提示1044解决方案
    Java equals(),== 和 hashcode()
    一键批处理图片的脚本(将指定目录中的图片处理成要求的分辨率)
    Anaconda环境下GPT2-Chinese的基本使用记录
    Ubuntu WSL 下编译并使用OpenJDK12
    SSM项目下Druid连接池的配置及数据源监控的使用
    《MySql必知必会》笔记整理
    Java面试题整理
    SpringBoot 访问树莓派上的MySql
  • 原文地址:https://www.cnblogs.com/autoint/p/10930216.html
Copyright © 2020-2023  润新知