• 【清华集训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;
    }
    
  • 相关阅读:
    2019学期第十周编程总结
    2019学期第九周编程总结
    第七次作业
    第六次作业
    第五次作业
    jsp第四次作业
    3.10
    3.4
    3.3jsp作业
    最后一次安卓作业
  • 原文地址:https://www.cnblogs.com/yanshannan/p/9662749.html
Copyright © 2020-2023  润新知