zoukankan      html  css  js  c++  java
  • HDU 5398(LCT)

    HDU - 5398(LCT)

    用LCT动态维护环

    这题需要我们弄一些小性质

    假设我们从大的数向小的数连边,那么一定是向大的数的因子连边,加入的边总数就是\(n\ln\)

    如果这条边已经存在,那么就要从当前产生的环上换下来,存一个最小值

    这样就是\(LCT\)模拟连边过程,总复杂度$n \cdot \log n \cdot \ln n $

    #include<cstdio>
    #include<cctype>
    #include<iostream>
    #include<vector>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    #define reg register
    typedef long long ll;
    #define rep(i,a,b) for(reg int i=a,i##end=b;i<=i##end;++i)
    #define drep(i,a,b) for(reg int i=a,i##end=b;i>=i##end;--i)
    
    char IO;
    int rd(){
    	int s=0,f=0;
    	while(!isdigit(IO=getchar())) if(IO=='-') f=1;
    	do s=(s<<1)+(s<<3)+(IO^'0');
    	while(isdigit(IO=getchar()));
    	return f?-s:s;
    }
    
    const int N=2e5+10;
    
    int n=1e5;
    vector <int> fac[N];
    int fa[N],son[N][2];
    int rev[N];
    struct Node{
    	int x,id;
    	Node operator + (const Node t) const{
    		Node res;
    		res.x=min(x,t.x);
    		if(res.x==x) res.id=id;
    		else res.id=t.id;
    		return res;
    	}
    } s[N],val[N];
    
    inline int dir(int x){ return son[fa[x]][1]==x; }
    inline int isroot(int x){ return !fa[x] || (son[fa[x]][0]!=x&&son[fa[x]][1]!=x); }
    
    void Up(int u) {
    	if(!u) return;
    	s[u]=val[u];
    	if(son[u][0]) s[u]=s[u]+s[son[u][0]];
    	if(son[u][1]) s[u]=s[u]+s[son[u][1]];
    }
    void Down(int u) {
    	if(!u||!rev[u]) return;
    	int t;
    	if(son[u][0]) {
    		t=son[u][0];
    		rev[t]^=1;
    		swap(son[t][0],son[t][1]);
    	}
    	if(son[u][1]) {
    		t=son[u][1];
    		rev[t]^=1;
    		swap(son[t][0],son[t][1]);
    	}
    	rev[u]=0;
    }
    
    int stk[N],top;
    int eu[N],ev[N];
    
    void rotate(int u) {
    	int f=fa[u],ff=fa[f];
    	Down(ff),Down(f),Down(u);
    	int d=dir(u);
    	fa[u]=ff; if(!isroot(f)) son[ff][dir(f)]=u;
    	son[f][d]=son[u][!d]; fa[son[u][!d]]=f;
    	fa[f]=u,son[u][!d]=f;
    	Up(f),Up(u),Up(ff);
    }
    
    void Splay(int x) {
    	Down(x),Up(x);
    	static int stk[N],top=0;
    	int t=x;
    	while(!isroot(t)) stk[++top]=t,t=fa[t];
    	stk[++top]=t;
    	while(top) Down(stk[top--]);
    	while(!isroot(x)) {
    		int f=fa[x];
    		if(!isroot(f)) {
    			if(dir(x)^dir(f)) rotate(x);
    			else rotate(f);
    		}
    		rotate(x);
    	}
    }
    
    
    
    void Access(int x){ for(int t=0; x; t=x,x=fa[x]) Splay(x),son[x][1]=t,Up(x); }
    void MakeRoot(int x) {
    	Access(x);
    	Splay(x);
    	rev[x]^=1;
    	swap(son[x][0],son[x][1]);
    }
    
    int GetRoot(int x) { 
    	Access(x);
    	Splay(x);
    	do {
    		Down(x);
    		if(!son[x][0]) break;
    		x=son[x][0];
    	} while(1);
    	Splay(x);
    	return x;
    }
    
    
    void Cut(int x,int y) {
    	MakeRoot(x);
    	Access(y);
    	Splay(x);
    	fa[y]=0;
    	son[x][1]=0;
    	Up(x);
    }
    
    
    ll ans;
    ll res[N];
    
    
    
    void Link(int x,int y,int w) {
    	if(GetRoot(x)==GetRoot(y)) {
    		MakeRoot(x);
    		Access(y);
    		Node t=s[y];
    		if(t.x>=w) return;
    		ans-=t.x;
    		Cut(eu[t.id],t.id);
    		Cut(ev[t.id],t.id);
    		son[t.id][0]=son[t.id][1]=fa[t.id]=rev[t.id]=0;
    		stk[++top]=t.id;
    	}
    	MakeRoot(y);
    	int t=stk[top--];
    	fa[t]=rev[t]=0,son[t][0]=son[t][1]=0,s[t]=val[t]=(Node){w,t};
    	eu[t]=x,ev[t]=y;
    	ans+=w;
    	fa[t]=x;
    	fa[y]=t;
    }
    
    
    
    int main(){
    	rep(i,n+1,2*n) stk[++top]=i;
    	rep(i,1,n) s[i]=val[i]=(Node){(int)1e9,i};
    	for(reg int i=1;i<=n;++i) for(reg int j=i+i;j<=n;j+=i) fac[j].push_back((int)i);
    	rep(i,2,n) {
    		drep(j,fac[i].size()-1,0) Link(i,fac[i][j],fac[i][j]);
    		res[i]=ans;
    	}
    	while(~scanf("%d",&n)) printf("%lld\n",res[n]);
    }
    
    
    
    
    
  • 相关阅读:
    ssh免密钥登陆的两种方式
    python 项目实战之装饰器
    python 项目实战之随机杀死程序
    python paramiko外部传参和内部调用命令的方法
    linux screen 工具
    shell删除三天前或者三天内的文件
    CentOS7.3安装Go运行和开发环境
    4.Linq to Xml
    30.第一个Linq 数据库查询
    html 图标库
  • 原文地址:https://www.cnblogs.com/chasedeath/p/12931392.html
Copyright © 2011-2022 走看看