zoukankan      html  css  js  c++  java
  • [HAOI2016]地图

    题意

    题目

    做法

    看到还有莫队+分块的神仙,反正我是没有想到的,没想到子树信息还能化成莫队???

    首先,这道题目明摆着仙人掌,然后处理子树信息线段树合并即可。

    这篇博客主要是记载我这另类的线段树合并的。

    这道题目的线段树合并比较奇怪,因为子树信息是可以重合的,甚至还不满足可加性。。。

    但是如果你能理解主席树的时间复杂度,你就可以知道这个并不是什么大问题。

    时间复杂度:(O((n+q)logn))

    空间复杂度:(O(nlog值域))

    #include<cstdio>
    #include<cstring>
    #define  N  110000
    #define  NN  210000
    #define  SN  6100000
    #define  M  320000
    using  namespace  std;
    inline  int  mymin(int  x,int  y){return  x<y?x:y;}
    inline  int  mymax(int  x,int  y){return  x>y?x:y;}
    class  EDGE
    {
    	public:
    		struct  node
    		{
    			int  y,next;
    		}a[M];int  len,last[NN];
    		void  ins(int  x,int  y){len++;a[len].y=y;a[len].next=last[x];last[x]=len;}
    }a1,a2;
    struct  node
    {
    	int  l,r,c1/*奇数次*/,c2/*偶数次*/;
    	bool  bk;//我的儿子是否是复制别人的 
    }tr[SN];int  len,rt[NN];
    inline  void  updata(int  x){tr[x].c1=tr[tr[x].l].c1+tr[tr[x].r].c1;tr[x].c2=tr[tr[x].l].c2+tr[tr[x].r].c2;}
    void  link(int  &x,int  l,int  r,int  k)
    {
    	if(l==r)
    	{
    		if(!x)x=++len,tr[x].c1=1;
    		else  if(tr[x].c1)tr[x].c1=0,tr[x].c2=1;
    		else  tr[x].c1=1,tr[x].c2=0;
    		return  ;
    	}
    	if(!x)x=++len;
    	int  mid=(l+r)>>1;
    	if(k<=mid)link(tr[x].l,l,mid,k);
    	else  link(tr[x].r,mid+1,r,k);
    	updata(x);
    }
    void  merge(int  &x,int  &y,int  l,int  r,int  dep)//另类合并 
    {
    	if(!y)return  ;
    	else  if(!x)
    	{
    		x=++len;
    		tr[x]=tr[y];
    		tr[x].bk=1;//直接等于y,但是修改不能直接修改,会改变子树的信息
    		return  ;
    	}
    	if(l==r)
    	{
    		int  tx=0,ty=0;
    		if(tr[x].c1==1)tx=1;
    		if(tr[y].c1==1)ty=1;
    		if((tx+ty)&1)tr[x].c1=1,tr[x].c2=0;
    		else  tr[x].c2=1,tr[x].c1=0;
    		return  ;
    	}
    	if(tr[x].bk==1)//不难证明,这样子产生的点数为nlogn
    	{
    		int  lc=0,rc=0;
    		if(tr[x].l)tr[lc=++len]=tr[tr[x].l],tr[lc].bk=1;
    		if(tr[x].r)tr[rc=++len]=tr[tr[x].r],tr[rc].bk=1;
    		//之前我直接创两个儿子节点是不行的,因为这样原本为空的儿子节点就变成可实实在在的儿子节点了。
    		tr[x].l=lc;tr[x].r=rc;
    		tr[x].bk=0;
    	}
    	int  mid=(l+r)>>1;
    	merge(tr[x].l,tr[y].l,l,mid,dep+1);merge(tr[x].r,tr[y].r,mid+1,r,dep+1);
    	updata(x);
    }
    int  findans(int  x,int  l,int  r,int  k,int  type)
    {
    	if(!x)return  0;
    	if(r<=k)return  type==0?tr[x].c2:tr[x].c1;
    	int  mid=(l+r)>>1;
    	if(mid>=k)return  findans(tr[x].l,l,mid,k,type);
    	else  return  findans(tr[x].l,l,mid,k,type)+findans(tr[x].r,mid+1,r,k,type);
    }
    int  dfn[N],low[N],sta[N],top,cnt,n,m,ti;
    void  dfs1(int  x)
    {
    	sta[++top]=x;dfn[x]=low[x]=++ti;
    	for(int  k=a1.last[x];k;k=a1.a[k].next)
    	{
    		int  y=a1.a[k].y;
    		if(!dfn[y])
    		{
    			dfs1(y);
    			low[x]=mymin(low[y],low[x]);
    			if(low[y]==dfn[x])
    			{
    				cnt++;
    				while(sta[top]!=y)a2.ins(n+cnt,sta[top--]);
    				a2.ins(n+cnt,sta[top--]);
    				a2.ins(x,n+cnt);
    			}
    		}
    		else  low[x]=mymin(low[x],dfn[y]);
    	}
    }
    int  fa[NN],val[N];
    void  dfs2(int  x)
    {
    	if(x<=n)link(rt[x],1,val[0],val[x]);
    	for(int  k=a2.last[x];k;k=a2.a[k].next)
    	{
    		int  y=a2.a[k].y;
    		if(y!=fa[x])
    		{
    			fa[y]=x;
    			dfs2(y);
    			merge(rt[x],rt[y],1,val[0],0);
    		}
    	}
    }
    int  main()
    {
    	scanf("%d%d",&n,&m);
    	for(int  i=1;i<=n;i++){scanf("%d",&val[i]);val[0]=mymax(val[i],val[0]);}
    	for(int  i=1;i<=m;i++)
    	{
    		int  x,y;scanf("%d%d",&x,&y);
    		a1.ins(x,y);a1.ins(y,x);
    	}
    	dfs1(1);
    	dfs2(1);
    	int  q;scanf("%d",&q);
    	for(int  i=1;i<=q;i++)
    	{
    		int  id,type,limit;scanf("%d%d%d",&type,&id,&limit);
    		printf("%d
    ",findans(rt[id],1,val[0],limit,type));
    	}
    	return  0;
    }
    
  • 相关阅读:
    IE(IE6/IE7/IE8)支持HTML5标签
    JSP获取header信息request列表
    【转】log4j 不同的模块 不同的级别 记录日志
    congo.aspx和congo.cs和ViewCart.aspx
    Cookie Code
    web打印
    将一个对象转化为字符串形式的默认方法
    察看页面时禁止所有键盘上的键
    控制台程序添加引用
    Response.Write Script
  • 原文地址:https://www.cnblogs.com/zhangjianjunab/p/13894759.html
Copyright © 2011-2022 走看看