zoukankan      html  css  js  c++  java
  • 【BZOJ4538】【HNOI2016】网络(树链剖分,线段树,堆)

    题目链接,我是真的懒得调题目的格式。。。

    题解

    树链剖分搞一下LCA
    把线段树弄出来
    这只是形式上的线段树
    本质上是维护一段区间的一个堆
    每次把堆插入节点,
    询问的时候查询线段树上的堆的最大值就行了
    但是在插入节点的时候
    把节点插入到非当前树链剖分经过的节点中
    这里要稍微处理一下。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<queue>
    #include<vector>
    #define MAX 110000
    #define lson (now<<1)
    #define rson (now<<1|1)
    using namespace std;
    inline int read()
    {
    	int x=0,t=1;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=-1,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return x*t;
    }
    struct Line
    {
    	int v,next;
    }e[MAX*2];
    struct Link
    {
    	int l,r;
    }li[MAX];
    struct Record
    {
    	int u,v,w;
    }tt[MAX];
    inline bool operator <(Link a,Link b)
    {
    	if(a.l!=b.l)return a.l<b.l;
    	else return a.r<b.r;
    }
    int size[MAX],hson[MAX];
    int h[MAX],cnt=1,dep[MAX],top[MAX],ff[MAX];
    inline void Add(int u,int v)
    {
    	e[cnt]=(Line){v,h[u]};
    	h[u]=cnt++;
    }
    struct PQ
    {
    	priority_queue<int> Q1;
    	priority_queue<int> Q2;
    	void push(int x)
    		{
    			Q1.push(x);
    		}
    	void del(int x)
    		{
    			Q2.push(x);
    		}
    	int top()
    		{
    			while(!Q2.empty()&&Q1.top()==Q2.top()){Q1.pop();Q2.pop();}
    			return Q1.empty()?-1:Q1.top();
    		}
    }t[MAX*5];
    int tim,N,M,dfn[MAX];
    void DFS1(int u,int f)
    {
    	size[u]=1;dep[u]=dep[f]+1;
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;
    		if(v==f)continue;
    		ff[v]=u;
    		DFS1(v,u);
    		size[u]+=size[v];
    		if(size[v]>size[hson[u]])hson[u]=v;
    	}
    }
    void DFS2(int u,int tp)
    {
    	top[u]=tp;dfn[u]=++tim;
    	if(hson[u])DFS2(hson[u],tp);
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;
    		if(v==ff[u]||v==hson[u])continue;
    		DFS2(v,v);
    	}
    }
    void Update(int now,int l,int r,int al,int ar,int k,int opt)
    {
    	if(al==l&&ar==r)
    	{
    		opt?t[now].del(k):t[now].push(k);
    		return;
    	}
    	int mid=(l+r)>>1;
    	if(ar<=mid)Update(lson,l,mid,al,ar,k,opt);
    	else if(al>mid)Update(rson,mid+1,r,al,ar,k,opt);
    	else{Update(lson,l,mid,al,mid,k,opt);Update(rson,mid+1,r,mid+1,ar,k,opt);}
    }
    int Query(int now,int l,int r,int x)
    {
    	if(l==r)return t[now].top();
    	int mid=(l+r)>>1;
    	int ans=t[now].top();
    	if(x<=mid)return max(ans,Query(lson,l,mid,x));
    	else return max(ans,Query(rson,mid+1,r,x));
    }
    void Happen(int u,int v,int opt,int xx)
    {
    	int qq=0;
    	while(top[u]!=top[v])
    	{
    		if(dep[top[u]]<dep[top[v]])swap(u,v);
    		li[++qq]=(Link){dfn[top[u]],dfn[u]};
    		u=ff[top[u]];
    	}
    	if(dep[u]<dep[v])swap(u,v);
    	li[++qq]=(Link){dfn[v],dfn[u]};
    	sort(&li[1],&li[qq+1]);
    	int Left=0;
    	for(int i=1;i<=qq;Left=max(Left,li[i++].r))
    		if(Left+1<li[i].l)Update(1,1,N,Left+1,li[i].l-1,xx,opt);
    	if(Left<N)Update(1,1,N,Left+1,N,xx,opt);
    }
    int main()
    {
    	freopen("4538.in","r",stdin);
    	N=read();M=read();
    	for(int i=1;i<N;++i)
    	{
    		int u=read(),v=read();
    		Add(u,v);Add(v,u);
    	}
    	DFS1(1,0);DFS2(1,1);
    	for(int i=1;i<=M;++i)
    	{
    		int opt=read();
    		if(opt==2)
    		{
    			int x=read();
    			printf("%d
    ",Query(1,1,N,dfn[x]));
    		}
    		else if(opt==1)
    		{
    			int r=read();
    			Happen(tt[r].u,tt[r].v,opt,tt[r].w);
    		}
    		else
    		{
    			tt[i]=(Record){read(),read(),read()};
    			Happen(tt[i].u,tt[i].v,opt,tt[i].w);
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    二维数组的查找问题
    将字符串编码成数值,求数值最大和问题(今日头条笔试题)
    链表的倒序打印
    求方程的近似解
    多边形构成问题(今日头条笔试题)
    各种语言数据类型大小
    luoguP1551 亲戚
    Codeforces 764 A-B
    Mixing Chemicals
    Day 8 of JZJX
  • 原文地址:https://www.cnblogs.com/cjyyb/p/7623995.html
Copyright © 2011-2022 走看看