zoukankan      html  css  js  c++  java
  • 【清华集训2016】温暖会指引我们前行

    http://www.zybuluo.com/ysner/note/1285137

    题面

    戳我

    解析

    既然题目中把字典序的定义倒过来了,就说明要我们动态维护最大生成树(温度)。
    显然只有(lct)能胜任这种操作。

    鉴于(lct)只能维护点权,所以我们对每条边新建一个点,点权为边长,然后新点与两端点相连。
    然后同时维护路径长度的和即可。

    注意修改点信息时要(splay)那个点。

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #define ll long long
    #define re register
    #define il inline
    #define ls t[0][x]
    #define rs t[1][x]
    #define fp(i,a,b) for(re int i=a;i<=b;i++)
    #define fq(i,a,b) for(re int i=a;i>=b;i--)
    using namespace std;
    const int N=5e5+100;
    int n,m,f[N],tag[N],t[2][N],sta[N],top,val[N],tem[N],p[N];
    ll s[N];
    struct dat{int u,v;}a[N];
    il ll gi()
    {
      re ll x=0,t=1;
      re char ch=getchar();
      while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
      if(ch=='-') t=-1,ch=getchar();
      while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
      return x*t;
    }
    il void upd(re int x)
    {
      s[x]=s[ls]+s[rs]+val[x];p[x]=x;
      if(ls&&tem[p[ls]]<tem[p[x]]) p[x]=p[ls];
      if(rs&&tem[p[rs]]<tem[p[x]]) p[x]=p[rs];
    }
    il int son(re int x){return x==t[1][f[x]];}
    il int isrt(re int x){return x!=t[0][f[x]]&&x!=t[1][f[x]];}
    il void rev(re int x){if(!x) return;swap(ls,rs);tag[x]^=1;}
    il void pushdown(re int x)
    {
      if(!tag[x]) return;
      rev(ls);rev(rs);tag[x]=0;
    }
    il void rotate(re int x)
    {
      re int y=f[x],z=f[y],c=son(x);
      t[c][y]=t[c^1][x];if(t[c][y]) f[t[c][y]]=y;
      f[x]=z;if(!isrt(y)) t[son(y)][z]=x;
      t[c^1][x]=y;f[y]=x;upd(y);
    }
    il void splay(re int x)
    {
      sta[top=1]=x;
      for(re int i=x;!isrt(i);i=f[i]) sta[++top]=f[i];
      while(top) pushdown(sta[top--]);
      for(re int y=f[x];!isrt(x);rotate(x),y=f[x])
        if(!isrt(y)) son(x)^son(y)?rotate(x):rotate(y);
      upd(x);
    }
    il void access(re int x){for(re int y=0;x;y=x,x=f[x]) splay(x),rs=y,upd(x);}
    il void makert(re int x){access(x);splay(x);rev(x);}
    il int findrt(re int x){access(x);splay(x);while(ls) x=ls;splay(x);return x;}
    il void split(re int x,re int y){makert(x);access(y);splay(y);}
    il void link(re int x,re int y){makert(x);f[x]=y;}
    il void cut(re int x,re int y){split(x,y);t[0][y]=f[x]=0;upd(y);}
    il int Query(re int x,re int y){split(x,y);return s[y];}
    int main()
    {
      n=gi();m=gi();
      fp(i,1,n) tem[i]=2e9;
      fp(i,1,m)
        {
          re char op[10];scanf("%s",op);
          if(op[0]=='f')
    	{
    	  re int id=gi()+n+1,u=gi()+1,v=gi()+1;
    	  tem[id]=gi(),val[id]=gi();
    	  a[id]=(dat){u,v};
    	  if(findrt(u)^findrt(v)) link(u,id),link(v,id);
    	  else
    	    {
    	      split(u,v);re int pos=p[v];
    	      if(tem[pos]<tem[id])
    		{
    		  cut(a[pos].u,pos);cut(a[pos].v,pos);
    		  link(u,id);link(v,id);
    		}
    	    }
    	}
          if(op[0]=='m')
    	{
    	  re int u=gi()+1,v=gi()+1;
    	  if(findrt(u)^findrt(v)) {puts("-1");continue;}
    	  printf("%d
    ",Query(u,v));
    	}
          if(op[0]=='c')
    	{
    	  re int id=gi()+n+1,w=gi();
    	  val[id]=w;splay(id);
    	}
        }
      return 0;
    }
    
  • 相关阅读:
    node
    github
    [模块] pdf转图片-pdf2image
    python 15 自定义模块 随机数 时间模块
    python 14 装饰器
    python 13 内置函数II 匿名函数 闭包
    python 12 生成器 列表推导式 内置函数I
    python 11 函数名 迭代器
    python 10 形参角度 名称空间 加载顺序
    python 09 函数参数初识
  • 原文地址:https://www.cnblogs.com/yanshannan/p/9662749.html
Copyright © 2011-2022 走看看