zoukankan      html  css  js  c++  java
  • [bzoj4538][HNOI2016]网络

    [bzoj4538][HNOI2016]网络

    标签: 树链剖分 线段树 优先队列


    题目链接

    题解

    这题其实用最暴力的方法就好。
    直接树剖,用线段树维护不在该区间的最大权值,这个可以用堆做到(删除操作的话就再开一个堆)。
    线段树有个细节,由于是区间修改,但是这个堆的话既不好合并又不好下传,我们更新直接更新到一段区间上,查询的时候就直接把这段区间的最大值跟答案取个max。(感觉自己讲的好迷,具体还是去看代码吧)

    Code

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<set>
    #include<map>
    using namespace std;
    #define ll long long
    #define REP(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)
    #define DREP(i,a,b) for(int i=(a),_end_=(b);i>=_end_;i--)
    #define EREP(i,a) for(int i=start[(a)];i;i=e[i].next)
    inline int read()
    {
    	int sum=0,p=1;char ch=getchar();
    	while(!(('0'<=ch && ch<='9') || ch=='-'))ch=getchar();
    	if(ch=='-')p=-1,ch=getchar();
    	while('0'<=ch && ch<='9')sum=sum*10+ch-48,ch=getchar();
    	return sum*p;
    }
    
    const int maxn=1e5+20;
    
    struct node {
    	int v,next;
    };
    
    node e[maxn*2];
    int cnt,start[maxn];
    
    void addedge(int u,int v)
    {
    	e[++cnt]=(node){v,start[u]};
    	start[u]=cnt;
    }
    
    int n,m;
    int dfn[maxn],times,deep[maxn],sz[maxn],top[maxn],fa[maxn],son[maxn];
    
    struct priority {
    	priority_queue <int> q1,q2;
    	int top()
    		{
    			while(!q1.empty() && !q2.empty() && q1.top()==q2.top())q1.pop(),q2.pop();
    			if(q1.empty())return 0;
    			return q1.top();
    		}
    	void push(int x)
    		{
    			q1.push(x);
    		}
    	void pop(int x)
    		{
    			q2.push(x);
    		}
    	bool empty()
    		{
    			while(q1.top()==q2.top())q1.pop(),q2.pop();
    			return q1.empty();
    		}
    };
    
    struct Node {
    	priority x;
    };
    Node c[maxn*4];
    
    #define lc (o<<1)
    #define rc (o<<1 | 1)
    #define left lc,l,mid
    #define right rc,mid+1,r
    
    void update(int ql,int qr,int type,int d,int o,int l,int r)
    {
    	if(ql>qr)return;
    	if(ql<=l && r<=qr)
    	{
    		if(type)c[o].x.push(d);
    		else c[o].x.pop(d);
    		return;
    	}
    	int mid=(l+r)>>1;
    	if(ql<=mid)update(ql,qr,type,d,left);
    	if(qr>mid)update(ql,qr,type,d,right);
    }
    
    int query(int x,int o,int l,int r)
    {
    	if(l==r)
    	{
    		return c[o].x.top();
    	}
    	int mid=(l+r)>>1;
    	if(x<=mid)return max(c[o].x.top(),query(x,left));
    	else return max(c[o].x.top(),query(x,right));
    }
    
    void dfs(int u)
    {
    	int Son=0;
    	sz[u]=1;
    	deep[u]=deep[fa[u]]+1;
    	EREP(i,u)
    	{
    		int v=e[i].v;
    		if(v==fa[u])continue;
    		fa[v]=u;
    		dfs(v);
    		sz[u]+=sz[v];
    		if(sz[Son]<=sz[v])Son=v;
    	}
    	son[u]=Son;
    }
    
    void dfs1(int u)
    {
    	dfn[u]=++times;
    	if(son[u])
    	{
    		top[son[u]]=top[u];
    		dfs1(son[u]);
    	}
    	EREP(i,u)
    	{
    		int v=e[i].v;
    		if(v==son[u] || v==fa[u])continue;
    		top[v]=v;
    		dfs1(v);
    	}
    }
    
    void init()
    {
    	n=read();m=read();
    	REP(i,1,n-1)
    	{
    		int u=read(),v=read();
    		addedge(u,v);
    		addedge(v,u);
    	}
    	dfs(1);
    	top[1]=1;
    	dfs1(1);
    }
    
    struct Query {
    	int u,v,w;
    };
    Query qu[maxn*2];
    
    int dl[maxn],dr[maxn],tot,sx[maxn];
    
    bool cmpsx(const int a,const int b)
    {
    	return dl[a]<dl[b];
    }
    
    void change(int u,int v,int w,int type)
    {
    	tot=0;
    	while(top[u]!=top[v])
    	{
    		if(deep[top[u]]<deep[top[v]])swap(u,v);
    		dl[++tot]=dfn[top[u]];
    		dr[tot]=dfn[u];
    		u=fa[top[u]];
    	}
    	if(deep[u]<deep[v])swap(u,v);
    	dl[++tot]=dfn[v],dr[tot]=dfn[u];
    	REP(i,1,tot)sx[i]=i;
    	sort(sx+1,sx+tot+1,cmpsx);
    
    	update(1,dl[sx[1]]-1,type,w,1,1,n);
    	REP(i,1,tot-1)
    	{
    		update(dr[sx[i]]+1,dl[sx[i+1]]-1,type,w,1,1,n);
    	}
    	update(dr[sx[tot]]+1,n,type,w,1,1,n);
    }
    
    void doing()
    {
    	REP(i,1,m)
    	{
    		int type=read();
    		if(type==2)
    		{
    			int x=read(),y=query(dfn[x],1,1,n);
    			printf("%d
    ",y==0?-1:y);
    		}
    		else if(type==0)
    		{
    			int u=read(),v=read(),w=read();
    			qu[i]=(Query){u,v,w};
    			change(u,v,w,1);
    		}else
    		{
    			int x=read();
    			change(qu[x].u,qu[x].v,qu[x].w,0);
    		}
    	}
    }
    
    int main()
    {
    	init();
    	doing();
    	return 0;
    }
    
    
    
  • 相关阅读:
    Mac Office2016 安装及破解
    Axure 下载安装
    MacBook Pro常用快捷键
    MySQL 关于case when结合group by用时的写法举例
    RFID第二次作业
    Javascript函数柯里化(curry)
    binarySearch二分查找——Javascript实现
    KMP算法——Javascript实现
    从输入 URL 到页面加载完成的过程中都发生了什么事情?
    丁又专老师作业——Java检测代码
  • 原文地址:https://www.cnblogs.com/gzy-cjoier/p/7623920.html
Copyright © 2011-2022 走看看