• 2959: 长跑


    传送门

    又是一道卡常题..因为只有link没有cut,判断两点有没有联通另开一个并查集,用find_root会T...

    lct维护,把环用并查集合并即可.

      1 //Achen
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<cstdlib>
      6 #include<vector>
      7 #include<cstdio>
      8 #include<queue>
      9 #include<cmath>
     10 #include<set>
     11 #include<map>
     12 #define For(i,a,b) for(int i=(a);i<=(b);i++)
     13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
     14 const int N=2e5+7;
     15 typedef int LL; 
     16 typedef double db;
     17 using namespace std;
     18 int n,m;
     19 
     20 template<typename T> void read(T &x) {
     21     char ch=getchar(); x=0; T f=1;
     22     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
     23     if(ch=='-') f=-1,ch=getchar();
     24     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
     25 }
     26 
     27 int fa[N],fa2[N];
     28 int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); }
     29 
     30 int find2(int x) { return x==fa2[x]?x:fa2[x]=find2(fa2[x]); }
     31 
     32 int p[N],ch[N][2],flip[N];
     33 LL sz[N],tsz[N],sum[N];
     34 #define lc ch[x][0]
     35 #define rc ch[x][1]
     36 void update(int x) { sum[x]=sum[lc]+sum[rc]+sz[x]; }
     37 
     38 void down(int x) {
     39     if(!flip[x]) return;
     40     swap(lc,rc);
     41     flip[lc]^=1;
     42     flip[rc]^=1;
     43     flip[x]^=1;
     44 }
     45 
     46 int isroot(int x) { p[x]=find(p[x]); return ch[p[x]][0]!=x&&ch[p[x]][1]!=x; }
     47 
     48 void rotate(int x) {
     49     int y=find(p[x]),z=find(p[y]),l=(x==ch[y][1]),r=l^1;
     50     if(!isroot(y)) ch[z][y==ch[z][1]]=x; p[x]=z;
     51     ch[y][l]=ch[x][r]; p[ch[x][r]]=y;
     52     ch[x][r]=y; p[y]=x;
     53     update(y); update(x);
     54 }
     55 
     56 void splay(int x) {
     57     static int g[N],top=0,tp;
     58     for(tp=x;!isroot(tp);tp=find(p[tp])) g[++top]=tp;
     59     g[++top]=tp;
     60     while(top) down(g[top--]);
     61     for(;!isroot(x);rotate(x)) {
     62         int y=find(p[x]),z=find(p[y]);
     63         if(!isroot(y)) ((x==ch[y][1])^(y==ch[z][1]))?rotate(x):rotate(y);
     64     }
     65 }
     66 
     67 void access(int x) {
     68     for(int t=0;x;x=find(p[t=x])) {
     69         splay(x);
     70         rc=t;
     71         update(x);
     72     }
     73 }
     74 
     75 void newroot(int x) {
     76     access(x);
     77     splay(x);
     78     flip[x]^=1;
     79 }
     80 
     81 void lik(int x,int y) {
     82     newroot(x);
     83     p[x]=y;
     84 }
     85 
     86 void change(int x,int y) {
     87     splay(x);
     88     sz[x]+=y;
     89     update(x);
     90 }
     91 
     92 void qry(int x,int y) {
     93     if(find2(x)!=find2(y)) {
     94         puts("-1"); return;
     95     }
     96     newroot(x);
     97     access(y);
     98     splay(y);
     99     printf("%d
    ",sum[y]);
    100 }
    101 
    102 LL tpsum=0;
    103 void dfs(int x,int FA) {
    104     tpsum+=sz[x];
    105     fa[x]=FA;
    106     if(lc) dfs(lc,FA);
    107     if(rc) dfs(rc,FA);    
    108 }
    109 
    110 void link_it(int x,int y) {
    111     int u=find(x),v=find(y);
    112     if(u==v) return;
    113     if(find2(u)==find2(v)) {
    114         newroot(u);
    115         access(v);
    116         splay(v);
    117         tpsum=0;
    118         dfs(v,v);
    119         sz[v]=sum[v]=tpsum; 
    120         ch[v][0]=ch[v][1]=0;
    121     }
    122     else { lik(u,v); fa2[find2(u)]=find2(v); }
    123 }
    124 
    125 //#define DEBUG
    126 int main() {
    127 #ifdef DEBUG
    128     freopen("1.in","r",stdin);
    129     //freopen(".out","w",stdout);
    130 #endif
    131     read(n); read(m);
    132     For(i,1,n) read(sz[i]),tsz[i]=sz[i],fa[i]=fa2[i]=i;
    133     For(ti,1,m) {
    134         int o,x,y;
    135         read(o); read(x); read(y);
    136         if(o==1) link_it(x,y);
    137         else if(o==2) change(find(x),y-tsz[x]),tsz[x]=y;
    138         else qry(find(x),find(y));
    139     }
    140     return 0;
    141 }
    View Code
    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<vector>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    #include<ctime>
    #include<set>
    #define For(i,a,b) for(int i=(a);i<=(b);i++)
    #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    typedef long long LL; 
    typedef double db;
    int vis[1000007],fa[100007],cnt[100008][11],ok[5007][5007];
    
    using namespace std;  
    
    int find(int x) { return x==fa[x]?x:find(fa[x]); }
    
    //#define DEBUG
    int main() {
    #ifdef DEBUG
    	//freopen("line.in","r",stdin);
    	freopen("std.in","w",stdout);
    #endif
        srand(time(0)); 
        int n=500,m=1000,c=10,q=500;
        printf("%d %d %d %d
    ",n,m,c,q);
        For(i,1,n*c) fa[i]=i;
        For(i,1,n) {
        	int x=rand()%10000+1;
        	printf("%d
    ",x);
        }
        For(i,1,m) {
        	int u,v,w;
        	u=rand()%n+1; v=rand()%n+1; w=rand()%c;
        	while(ok[u][v]||cnt[u][w]+1>2||cnt[v][2]+1>2||(find(w*n+u)==find(w*n+v))) {
        		u=rand()%n+1;
        		v=rand()%n+1;
        		w=rand()%c;
        	}
        	ok[u][v]=1;
        	fa[find(w*n+u)]=find(w*n+v);
        	cnt[u][w]++; cnt[v][w]++;
        	printf("%d %d %d
    ",u,v,w);
        }
        For(i,1,q) {
        	int o=rand()%3;
        	if(o==0) {
        		int x=rand()%n+1,y=rand()%10000+1;
        		printf("%d %d %d
    ",o,x,y);
        	}
        	else if(o==1) {
        		int u=rand()%n+1,v=rand()%n+1,w=rand()%c;
        		printf("%d %d %d %d
    ",o,u,v,w);
        	}
        	else {
        		int w=rand()%c,u=rand()%n+1,v=rand()%n+1;
        		while(u==v) { u=rand()%n+1; v=rand()%n+1; }
        		printf("%d %d %d %d
    ",o,w,u,v);
        	}
        }
        return 0;  
    }  
    
  • 相关阅读:
    Windows7安装SQL Server 2008图解
    【Android病毒分析报告】
    linux source命令学习
    SQL学习笔记——SQL初入门,Ubuntu下MySQL的安装
    挂断电话的实现(即类似于电话号码黑名单)
    35+雪花Logos设计灵感
    jdk8预览
    PL/SQL --> 动态SQL调用包中函数或过程
    VMware 彻底删除虚拟机操作系统的方法
    Ubuntu 16.04 LTS: apt-get update 失败处理 Aborted (core dumped)
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8981457.html
Copyright © 2020-2023  润新知