zoukankan      html  css  js  c++  java
  • bzoj 3307: 雨天的尾巴【树剖lca+树上差分+线段树合并】

    这居然是我第一次写线段树合并……所以我居然在合并的时候加点结果WAWAWAMLEMLEMLE……!ro的时候居然直接指到la就行……
    树上差分,每个点建一棵动态开点线段树,然后统计答案的时候合并即可

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    const int N=100005;
    int n,m,h[N],cnt,de[N],fa[N],si[N],hs[N],fr[N],c[N],rt[N],tot,ans[N],d[N];
    struct qwe
    {
    	int ne,to;
    }e[N<<1];
    struct xds
    {
    	int ls,rs,mx,p;
    }t[7500005];
    int read()
    {
    	int r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    void add(int u,int v)
    {
    	cnt++;
    	e[cnt].ne=h[u];
    	e[cnt].to=v;
    	h[u]=cnt;
    }
    void dfs1(int u,int fat)
    {
        fa[u]=fat;
        de[u]=de[fat]+1;
        si[u]=1;
        for(int i=h[u];i;i=e[i].ne)
            if(e[i].to!=fat)
            {
                dfs1(e[i].to,u);
    			d[u]++;
                si[u]+=si[e[i].to];
                if(si[e[i].to]>si[hs[u]])
                    hs[u]=e[i].to;
            }
    }
    void dfs2(int u,int top)
    {
        fr[u]=top;
        if(!hs[u])
            return;
        dfs2(hs[u],top);
        for(int i=h[u];i;i=e[i].ne)
            if(e[i].to!=fa[u]&&e[i].to!=hs[u])
                dfs2(e[i].to,e[i].to);
    }
    int lca(int u,int v)
    {//cerr<<u<<"    "<<v<<endl;
        for(;fr[u]!=fr[v];de[fr[u]]>de[fr[v]]?u=fa[fr[u]]:v=fa[fr[v]]);
        return de[u]<de[v]?u:v;
    }
    void ud(int ro)
    {
    	if(t[ro].ls&&t[t[ro].ls].mx>=t[t[ro].rs].mx)
    		t[ro].p=t[t[ro].ls].p,t[ro].mx=t[t[ro].ls].mx;
    	else
    		t[ro].p=t[t[ro].rs].p,t[ro].mx=t[t[ro].rs].mx;
    }
    void update(int &ro,int l,int r,int p,int v)
    {
    	if(!ro)
    		ro=++tot,t[ro].p=l;
    	if(l==r)
    	{//cerr<<p<<"   "<<v<<" "<<t[ro].mx<<endl;
    		t[ro].mx+=v;
    		return;
    	}
    	int mid=(l+r)>>1;
    	if(p<=mid)
    		update(t[ro].ls,l,mid,p,v);
    	else
    		update(t[ro].rs,mid+1,r,p,v);
    	ud(ro);
    }
    void hb(int &ro,int la,int l,int r)
    {
    	if(!la)
    		return;
    	if(!ro)
    	{
    		ro=la;
    		return;
    	}
    	if(l==r)
    	{
    		t[ro].mx+=t[la].mx;
    		return;
    	}
    	int mid=(l+r)>>1;
    	hb(t[ro].ls,t[la].ls,l,mid);
    	hb(t[ro].rs,t[la].rs,mid+1,r);
    	ud(ro);
    }
    // void dfs(int u)
    // {
    	// for(int i=h[u];i;i=e[i].ne)
    		// if(e[i].to!=fa[u])
    		// {
    			// dfs(e[i].to);
    			// hb(rt[u],rt[e[i].to],1,100000);
    		// }
    	// if(t[rt[u]].mx<=0)
    		// ans[u]=0;
    	// else
    		// ans[u]=t[rt[u]].p;//cerr<<u<<" "<<t[rt[u]].mx<<endl;
    // }
    int main()
    {
    	n=read(),m=read();
    	for(int i=1;i<n;i++)
    	{
    		int x=read(),y=read();
    		add(x,y),add(y,x);
    	}
    	dfs1(1,0);
    	dfs2(1,1);
    	t[0].mx=-1e9;
    	while(m--)
    	{
    		int x=read(),y=read(),z=read(),lc=lca(x,y);
    		update(rt[x],1,100000,z,1);
    		update(rt[y],1,100000,z,1);
    		update(rt[lc],1,100000,z,-1);
    		if(fa[lc])
    			update(rt[fa[lc]],1,100000,z,-1);
    		// cerr<<t[rt[x]].p<<" "<<t[rt[x]].mx<<"   "<<t[rt[y]].p<<" "<<t[rt[y]].mx<<"   "<<t[rt[lc]].p<<" "<<t[rt[lc]].mx<<"   "<<t[rt[fa[lc]]].p<<" "<<t[rt[fa[lc]]].mx<<"   "<<endl;
    	}
    	// dfs(1);
    	queue<int>q;
    	for(int i=1;i<=n;i++)
    		if(!d[i])
    			q.push(i);
    	while(!q.empty())
    	{
    		int u=q.front();//cerr<<u<<endl;
    		q.pop();
    		for(int i=h[u];i;i=e[i].ne)
    			if(e[i].to!=fa[u])
    				hb(rt[u],rt[e[i].to],1,100000);
    		if(t[rt[u]].mx<=0)
    			ans[u]=0;
    		else
    			ans[u]=t[rt[u]].p;
    		if(!(--d[fa[u]]))
    			q.push(fa[u]);
    	}
    	for(int i=1;i<=n;i++)
    		printf("%d
    ",ans[i]);
    	return 0;
    }
    
  • 相关阅读:
    Django准备知识-web应用、http协议、web框架、Django简介
    Django
    MySQL(基本语句)
    jsvascript === 和==的区别
    控制input只能输入1-200范围的数字
    删除数组中指定的某个元素
    微信授权登陆绑定
    通过GZ代替document.getElementById()
    判断浏览器版本
    截取逗号后面所有字符
  • 原文地址:https://www.cnblogs.com/lokiii/p/9674380.html
Copyright © 2011-2022 走看看