HNOI2016 网络

 身为一个强省(HN)+强校(CJ)的蒟蒻,天天gi烂。。我还能说什么呢。

于是在一堆大佬的鼓(you)励(pian)下,去做了一下HNOI2016的网络。。。

(其实是一位名叫网管的人给我们的LCA练习题(rand的))

至于正解,当年HNOI2016考场上没有人做出正解来,所以我肯定只会打暴力。

1.首先这是一堆对于链上的操作,所以我们很容易联想到树链剖分。

2.然后要求不被影响的最大值,即不经过他的最大值,这可以想到用堆来维护。

4.因为设计删除操作,我们就可以维护一个加入堆和一个删除堆,要top的时候如果两个堆的队首相同,就一直pop;

5.运用正难则反的思想,既然维护经过他的很难的话,那我们就对树链剖分后的线段树的每个节点维护不经过他的最大值;

6.那么如何维护不经过他的呢?首先在树链剖分跳LCA的时候,把跳的那些线段全部记录下来,因为跳的这些线段都是连续的,所以我们排一遍序,取这些夹在线段中间的区间进行修改即可。

7.而查询的时候就一路查下来并不断取MAX即可;

// MADE BY QT666
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define lson num<<1
#define rson num<<1|1
using namespace std;
typedef long long ll;
const int N=300050;
int gi()
{
  int x=0,flag=1;
  char ch=getchar();
  while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}
  while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
  return x*flag;
}
int head[N],nxt[N*2],to[N*2],dfn[N],top[N],size[N],son[N],sum,dep[N],fa[N],n,m,tt;
struct ac
{
  priority_queuea,d;
  void push(int x) {a.push(x);}
  void del(int x) {d.push(x);}
  int top()
  {
    while(!d.empty()&&a.top()==d.top()) a.pop(),d.pop();
	if(a.empty()) return -1;
	return a.top();
  }
}tree[N*5];
struct AC
{
  int l,r;
}Data[N];
struct Ac
{
  int x,y,z;
}q[N];
void dfs1(int x,int f)
{
  dep[x]=dep[f]+1;size[x]=1;
  for(int i=head[x];i;i=nxt[i])
    {
      int y=to[i];
      if(y!=f)
	{
	  dfs1(y,x);
	  fa[y]=x;
	  size[x]+=size[y];
	  if(size[y]>size[son[x]]) son[x]=y;
	}
    }
}
void dfs2(int x,int f)
{
  dfn[x]=++sum,top[x]=f;
  if(son[x]) dfs2(son[x],f);
  for(int i=head[x];i;i=nxt[i])
    {
      int y=to[i];
      if(y!=fa[x]&&y!=son[x]) dfs2(y,y);
    }
}
void modify(int num,int l,int r,int L,int R,int type,int val)
{
  if(L>R) return;
  if(L<=l&&r<=R)
    {
      if(!type) tree[num].push(val);
      else tree[num].del(val);
      return;
    }
  int mid=(l+r)>>1;
  if(L<=mid) modify(lson,l,mid,L,R,type,val);
  if(R>mid) modify(rson,mid+1,r,L,R,type,val);
}
bool cmp(AC a,AC b)
{
  return a.l>1;
  if(x<=mid) return max(tree[num].top(),query(lson,l,mid,x));
  else return max(tree[num].top(),query(rson,mid+1,r,x));
}
int main()
{
  int x,y,z,type;
  n=gi(),m=gi();
  for(int i=1;i


你可能感兴趣的:(HNOI2016 网络)