板子集合

放一块方便复习,以及一些懒得写博客的新学知识点

tarjan

点击查看代码
//缩点
void tarjan(int u){
    dfn[u]=low[u]=++t;
    s[++top]=u;vis[u]=1;
    for(int i=0;i<g[u].size();++i){
        int v=g[u][i];
        if(!dfn[v]){
            tarjan(v);low[u]=min(low[u],low[v]);
        }else  if(vis[v])  low[u]=min(low[u],low[v]);
    }if(dfn[u]==low[u]){
        vis[u]=0;
        c[++sum]++;fa[u]=sum;
        while(s[top]^u){
            vis[st[top]]=0;
            c[sum]++;fa[s[top--]]=sum;
        }--top;
    }
}
//割点
void tarjan(int u){
    dfn[u]=low[u]=++t;int f=0;
    for(int i=0;i<g[u].size();++i){
        int v=g[u][i];
        if(!dfn[v]){
            tarjan(v);
            low[u]=min(low[u],low[v]);
            if(dfn[u]<=low[v])  ++f;
        }else  low[u]=min(low[u],dfn[v]);
    }if((u==rt&&f>1)||(u!=rt&&f))  q.push(u);
}
//割边
void tarjan(int u){
    dfn[u]=low[u]=++t;int f=0;
    for(int i=0;i<g[u].size();++i){
        int v=g[u][i];
        if(!dfn[v]){
            tarjan(v);
            low[u]=min(low[u],low[v]);
            if(dfn[u]<low[v])  a[++cnt]={min(u,v),max(u,v)};
        }else  low[u]=min(low[u],dfn[v]);
    }
}
//点双
void tarjan(int u){
    dfn[u]=low[u]=++t;st[++top]=u;int f=0;
    for(int i=0;i<g[u].size();++i){
        int v=g[u][i];
        if(!dfn[v]){
            tarjan(v);
            low[u]=min(low[u],low[v]);++f;
            if(dfn[u]<=low[v]){
                a[++ans].push_back(u);
                while(st[top+1]!=v)  a[ans].push_back(st[top--]);
            }  
        }else  low[u]=min(low[u],dfn[v]);
    }if(u==rt&&!f)  a[++ans].push_back(u);
}
//边双
void tarjan(int u,int fa){
    dfn[u]=low[u]=++t;s[++top]=u;
    for(in ti=0;i<g[u].size();++i){
        int v=g[u][i];
        if(!dfn[v]){
            tarjan(v,u);
            if(low[v]>=dfn[u])  continue;
            low[u]=min(low[u],low[v]);
        }else  if(v^fa)  low[u]=min(low[u],low[v]);
    }if(dfn[u]==low[u]){
        vis[u]=0;fa[u]=++sum;
        while(s[top]^u){
            vis[s[top]]=0;f[s[top--]]=sum;
        }--top;
    }
}

2-SAT

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int MAX=2e6+10;
int n,m,x,y,z1,z2,id[MAX][2],dfn[MAX],fa[MAX],low[MAX],s[MAX],t,top,vis[MAX],sum;
int tot,head[MAX];
struct edge{
    int t,nxt;
} e[MAX];
inline int read(){
	int x=0,f=1;char c=getchar();
	while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
	while(c<='9'&&c>='0'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
	return x*f;
}
inline void add(int a,int b){
	e[++tot].t=b;e[tot].nxt=head[a];head[a]=tot;
}void tarjan(int u){
	dfn[u]=low[u]=++t;s[++top]=u;vis[u]=1;
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].t;
		if(!dfn[v]){
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}else  if(vis[v])  low[u]=min(low[u],dfn[v]);	
	}if(dfn[u]==low[u]){
		vis[u]=0;
		fa[u]=++sum;
		while(s[top]!=u){
			vis[s[top]]=0;
			fa[s[top--]]=sum;
		}top--;
	}
}
int main(){
    n=read();m=read();
    for(int i=1,p=0;i<=n;++i)
        for(int j=0;j<=1;++j)  id[i][j]=++p;
    for(int i=1;i<=m;++i){
        x=read();z1=read();y=read();z2=read();
        add(id[x][!z1],id[y][z2]);add(id[y][!z2],id[x][z1]);
    }for(int i=1;i<=n<<1;++i)
        if(!dfn[i])  tarjan(i);
    for(int i=1;i<=n;++i)
        if(fa[id[i][0]]==fa[id[i][1]]){
            cout<<"IMPOSSIBLE";return 0;
        }  
    printf("POSSIBLE\n");
    for(int i=1;i<=n;++i)
        cout<<(fa[id[i][0]]>fa[id[i][1]])<<" ";
    
}

二次剩余

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int T,n,mod,a,x0,x1,ii;
struct com{
    int r,i;
};
inline com operator*(com x,com y){
    return {(x.r*y.r+ii*x.i%mod*x.i%mod)%mod,(x.i*y.r+x.r*y.i)%mod};
}
inline int read(){
	int x=0,f=1;char c=getchar();
	while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^'0');c=getchar();}
	return x;
}
inline int power(int a,int b){
    int res=1;
    while(b){
        if(b&1)  res=res*a%mod;
        a=a*a%mod;b>>=1;
    }return res;
}inline com power(com a,int b){
    com res={1,0};
    while(b){
        if(b&1)  res=res*a;
        a=a*a;b>>=1;
    }return res;
}inline void solve(){
    do{
        a=rand()%mod;
    }while(!a||power((a*a%mod-n+mod)%mod,mod-1>>1)==1);
    ii=(a*a%mod-n+mod)%mod;
    x0=power({a,1},mod+1>>1).r;x1=mod-x0;
}
signed main(){ 
    T=read();srand(time(0));
    while(T--){
        n=read();mod=read();
        if(n==0){printf("0\n");continue;}
        if(power(n,mod-1>>1)^1){printf("Hola!\n");continue;}
        solve();printf("%lld %lld\n",x0,x1);
    }
}
                                        

posted @ 2024-01-23 20:13  yisiwunian  阅读(14)  评论(0编辑  收藏  举报