一些模板

倍增LCA

#include<bits/stdc++.h>
#define F( i,a,b ) for( int i=(a);i<=(b);i++ )
#define F_2( i,a,b ) for( int i=(a);i>=(b);i-- )
#define LL long long
#define oo 0x7fffffff
#define N 101
#define M 10001
using namespace std;

int read()
{
    int f=1,s=0;
    char ch=getchar();
    while( ch<'0' || ch>'9' ) { if( ch=='-' ) f=-1; ch=getchar(); }
    while( ch>='0' && ch<='9' ) { s=( s<<1 )+( s<<3 )+ch-'0'; ch=getchar(); }
    return f*s;
}

int m,n,maxd,maxa,cnt;
int a[N],head[N],dep[N],vis[N];
int anc[N][101],fa[N];
struct edge{
    int to,nxt;
}e[N*2];

void addedge( int cu,int cv )
{
    cnt++;
    e[cnt].to=cv;
    e[cnt].nxt=head[cu];
    head[cu]=cnt;
} 

void dfs( int u )
{
    vis[u]=1;
    for( int i=head[u];i;i=e[i].nxt )
    {
        int v=e[i].to;
        if( !vis[v] )
        {
            fa[v]=u;
            dep[v]=dep[u]+1;
            dfs( v );
            maxd=max( maxd,dep[v] );
        }
    }
}

void init()
{
    maxa=log2( maxd )+1;
    F( i,1,n )
    {
        anc[i][0]=fa[i];
    }
    F( j,1,maxa )
    {
        F( i,1,n )
        {
            anc[i][j]=anc[anc[i][j-1]][j-1];
        }
    }
}

int lca( int x,int y )
{
    if( dep[x]<dep[y] )
    {
        int t=x;
        x=y;
        y=t;
    }
    F_2( i,maxa,0 )
    {
        if( dep[y]<=dep[anc[x][i]] )
        {
            x=anc[x][i];
        }
    }
    if( x==y )
        return x;
    F_2( i,maxa,0 )
    {
        if( anc[x][i]!=anc[y][i] )
        {
            x=anc[x][i];
            y=anc[y][i];
        }
    }
    return anc[x][0];
}

int main()
{
    n=read();
    F( i,1,n-1 )
    {
        int tu,tv;
        tu=read();
        tv=read();
        addedge( tu,tv );
        addedge( tv,tu );
    }
    dep[1]=1;
    dfs( 1 );
    init();
    F( i,1,n )
        F( j,i+1,n )
            cout<<i<<" "<<j<<" "<<lca( i,j )<<endl;
    return 0;
}

Pollard Rho 大整数分解

#include <iostream>  
#include <stdlib.h>  
#include <string.h>  
#include <algorithm>  
#include <stdio.h>  
const int Times = 10;  
const int N = 5500;  

using namespace std;  
typedef long long LL;  

LL ct, cnt;  
LL fac[N], num[N];  

LL gcd(LL a, LL b)  
{  
    return b? gcd(b, a % b) : a;  
}  

LL multi(LL a, LL b, LL m)  
{  
    LL ans = 0;  
    a %= m;  
    while(b)  
    {  
        if(b & 1)  
        {  
            ans = (ans + a) % m;  
            b--;  
        }  
        b >>= 1;  
        a = (a + a) % m;  
    }  
    return ans;  
}  

LL quick_mod(LL a, LL b, LL m)  
{  
    LL ans = 1;  
    a %= m;  
    while(b)  
    {  
        if(b & 1)  
        {  
            ans = multi(ans, a, m);  
            b--;  
        }  
        b >>= 1;  
        a = multi(a, a, m);  
    }  
    return ans;  
}  

bool Miller_Rabin(LL n)  
{  
    if(n == 2) return true;  
    if(n < 2 || !(n & 1)) return false;  
    LL m = n - 1;  
    int k = 0;  
    while((m & 1) == 0)  
    {  
        k++;  
        m >>= 1;  
    }  
    for(int i=0; i<Times; i++)  
    {  
        LL a = rand() % (n - 1) + 1;  
        LL x = quick_mod(a, m, n);  
        LL y = 0;  
        for(int j=0; j<k; j++)  
        {  
            y = multi(x, x, n);  
            if(y == 1 && x != 1 && x != n - 1) return false;  
            x = y;  
        }  
        if(y != 1) return false;  
    }  
    return true;  
}  

LL pollard_rho(LL n, LL c)  
{  
    LL i = 1, k = 2;  
    LL x = rand() % (n - 1) + 1;  
    LL y = x;  
    while(true)  
    {  
        i++;  
        x = (multi(x, x, n) + c) % n;  
        LL d = gcd((y - x + n) % n, n);  
        if(1 < d && d < n) return d;  
        if(y == x) return n;  
        if(i == k)  
        {  
            y = x;  
            k <<= 1;  
        }  
    }  
}  

void find(LL n, int c)  
{  
    if(n == 1) return;  
    if(Miller_Rabin(n))  
    {  
        fac[ct++] = n;  
        return ;  
    }  
    LL p = n;  
    LL k = c;  
    while(p >= n) p = pollard_rho(p, c--);  
    find(p, k);  
    find(n / p, k);  
}  

int main()  
{  
    LL n;  
    while(cin>>n)  
    {  
        ct = 0;  
        find(n, 120);  
        sort(fac, fac + ct);  
        num[0] = 1;  
        int k = 1;  
        for(int i=1; i<ct; i++)  
        {  
            if(fac[i] == fac[i-1])  
                ++num[k-1];  
            else  
            {  
                num[k] = 1;  
                fac[k++] = fac[i];  
            }  
        }  
        cnt = k;  
        for(int i=0; i<cnt; i++)  
            cout<<fac[i]<<"^"<<num[i]<<" ";  
        cout<<endl;  
    }  
    return 0;  
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值