置换专题

UVA 10294 Arif in Dhaka (First Love Part 2)

一个n个珠子的环形首饰,每个珠子可能的颜色有t种。
考虑旋转,考虑旋转和翻转,分别有几种本质不同的首饰。

考虑旋转有n种,若逆时针旋转i颗珠子,则 i,2i,3i 构成循环,这个循环有 n/gcd(i,n) 个元素,共有 gcd(i,n) 个循环,置换的不同点个数为 n1i=0tgcd(i,n)

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
const int maxn = 51;
int n,t;
ll gcd(int a,int b){if (!b) return a;return gcd(b,a%b);}
int main()
{
//  freopen("uva10294.in","r",stdin);
//  freopen(".out","w",stdout);

    while(cin>>n>>t) {
        ll pow[maxn]={1};
        For(i,n) pow[i]=pow[i-1]*t;
        ll a=0,b=0;
        Rep(i,n) a+=pow[gcd(n,i)];
        b = (n%2) ? ( n*pow[(n+1)/2] ) : ( n/2 * pow[n/2] * ( 1 + t ) );
        cout<<a/n<<' '<<(a+b)/2/n<<endl;
    }

    return 0;
}

UVA 12103 Leonardo’s Notebook

题意:已知置换 B ,求置换A,使 A2=B

找规律:

(a1,a2,a3)(a1,a2,a3)=(a1,a3,a2)

(b1,b2,b3,b4)(b1,b2,b3,b4)=(b1,b3)(b2,b4)

倒推,对B的每个循环节,尽量拆成若干奇数循环节+长度相等的若干对循环节

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
const int MAXN = 100;
int h[1000],cnt[MAXN];
bool vis[MAXN];
int main()
{
//  freopen("uva12103.in","r",stdin);
//  freopen(".out","ws",stdout);

    int T=read();
    while(T--) {
        MEM(vis) MEM(cnt)
        char s[50];
        cin>>s;
        Rep(i,26) h[i]=s[i]-'A';
        bool flag=0;
        Rep(i,26) if (!vis[i]) {
            int j=i,n=0;
            do {
                vis[j]=1;
                ++n;
                j=h[j];
            } while (!vis[j]);
            if (n%2==0) cnt[n]++;
        }           
        For(i,26) if (cnt[i]%2) flag=1;     
        if (flag) puts("No"); else puts("Yes");
    }


    return 0;
}

UVA 11077 Find the Permutations

题意:给一个排列,每次两两交换,问至少几次能把排列变为 (1,2,...,n)

单个元素循环,交换次数0
2个元素循环,交换次数1,
3个元素循环,交换次数2,
。。
定理:c个元素的循环交换c-1次

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
const int MAXN = 22;
ull f[MAXN][MAXN];
int main()
{
//  freopen("uva11077.in","r",stdin);
//  freopen(".out","w",stdout);

    MEM(f) 
    f[0][0]=1;
    For(i,21) {
        f[i][0]=1;
        For(j,21) {
            f[i][j] = f[i-1][j-1] * (i-1) + f[i-1][j];  
        }
    }
    int n,k;
    while (cin>>n>>k && n) {
        cout<<f[n][k]<<endl;    
    } 

    return 0;
}

UVA 1156 Pixel Shuffle

题意:给一个像素图的若干置换,问重复几次变为原样。

把操作转成置换,然后求循环长度的最小公倍数

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 

int gcd(int a,int b){if (!b) return a;return gcd(b,a%b); }
int lcm(int a,int b){return a/gcd(a,b)*b;}

const int MAXN = 1025;

int n,a[MAXN*MAXN],a2[MAXN*MAXN];
int ID(int i,int j) {
    return i*n+j;
}
int new_pos(int i,int j,string s) {
    if (s[0]=='i') {
        return ID(i,j);
    } else if (s[0]=='r') {
        return ID(n-j-1,i);
    } else if (s[0]=='s') {
        return ID(i,n-1-j); 
    } else if (s[0]=='b'&&s[1]=='h') {
        if (i>=n/2) return ID(i,n-1-j); return ID(i,j);
    } else if (s[0]=='b'&&s[1]=='v') {
        if (i>=n/2) return ID(n-i+n/2-1,j); return ID(i,j); 
    } else if (s[0]=='d') {
        return ID( (i%2)? (n/2+i/2) : (i/2) ,j );
    } else if (s[0]=='m') {
        if (i%2) {
            if (j<n/2) return ID(i-1,j*2+1);
            return ID(i,(j-n/2)*2+1);
        } else {
            if (j<n/2) return ID(i,j*2);
            return ID(i+1,(j-n/2)*2);
        }
    } else return ID(i,j);
}

void work(string s) {
    int len=s.size();
    bool flag= s[len-1]=='-';
    Rep(i,n) Rep(j,n) {
        int p=ID(i,j),p2=new_pos(i,j,s);
        if (!flag) a2[p2]=a[p];
        else a2[p]=a[p2];
    }
    Rep(i,n*n) a[i]=a2[i];
}

bool vis[MAXN*MAXN];
void solve() {
    MEM(vis)
    int ans=1;
    Rep(i,n*n) if (!vis[i]) {
        int p=i,n2=0;
        do {
            vis[p]=1;
            n2++;
            p=a[p];
        } while (!vis[p]);
        ans=lcm(ans,n2);
    }
    cout<<ans<<endl;
}

int main()
{
//  freopen("uva1156.in","r",stdin);
//  freopen(".out","w",stdout);
//  
    int T=read();

    For(kcase,T) {
        if (kcase>1) puts("");
        scanf("%d\n",&n); 
        Rep(i,n*n) a[i]=i; 
        string line,temp;
        getline(cin,line);
        stringstream ss(line);
        stack<string> v;
        while (ss >> temp ) {
            v.push(temp); 
        }
        while(!v.empty()) work(v.top()),v.pop();

        solve();


    }

    return 0;
}

UVA 10601 Cubes

题意:给12根木棒(每个木棒颜色已知,等长),求能组成的本质不同的立方体个数

有24种置换,要耐心分析:

情况置换个数
不动12(1)1
左转3(4)6
左转*26(2)3
左转,上转4(3)8
左转,上转*22(1)5(2)6
合计24
#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (12 +  10)
#define MAXM (6+1)
int a[MAXM],b[MAXM],n;

ll C[MAXN][MAXN];
void init(int n) {
    C[0][0]=1;
    For(i,n) {
        C[i][0]=1;
        For(j,n) C[i][j]=C[i-1][j] + C[i-1][j-1]; 
    }
}
ll solve(int k) { //每k个一循环 
    int n=0;
    For(i,6) {
        if (a[i]%k) return 0;
        n+=a[i]/k;
    }
    ll ans=1;
    For(i,6) {
        ans *= C[n][a[i]/k];
        n-=a[i]/k;
    }
    return ans;
}
int main()
{
//  freopen("uva10601.in","r",stdin);
//  freopen(".out","w",stdout);
    init(12);
    int T = read();
    while (T--) {
        int n=12;
        MEM(a)
        For(i,n){
            a[read()]++; 
        }

        ll ans= solve(1) + 6*solve(4) + 3*solve(2) + 8*solve(3) ;

        For(i,6) For(j,6) {
            a[i]--; a[j]--;
            if (a[i]>=0 && a[j]>=0) ans+=6*solve(2);
            a[i]++; a[j]++;

        }


        printf("%lld\n",ans/24);
    } 



    return 0;
}

UVA 11330 Andy’s Shoes

裸题

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans);
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (10000+10)
int h[MAXN],t[MAXN];
bool vis[MAXN];
int main()
{
//  freopen("uva11330.in","r",stdin);
//  freopen(".out","w",stdout);
    int T=read();
    while(T--) {
        int n=read();
        For(i,n) {
            int a=read(),b=read();
            h[b]=a;
            t[i]=a;
        }   
        int ans=n;
        MEM(vis)
        For(i,n) {
            if (!vis[t[i]]) {
                int p=t[i];
                while (!vis[p]) {
                    vis[p]=1;
                    p=h[p];
                }
                --ans;
            }
        }   
        cout<<ans<<endl;
    }


    return 0;
}

UVA 11774 Doom’s Day

找规律

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans);
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
ll gcd(ll a,ll b){if (!b) return a;return gcd(b,a%b);}
int main()
{
//  freopen("uva11774.in","r",stdin);
//  freopen(".out","w",stdout);

    int T=read();
    For(kcase,T) {

        ll a=read(),b=read();
        ll g=gcd(a,b);
        a/=g; b/=g;

        Pr(kcase,a+b)
    } 


    return 0;
}

UVA 11540 Sultan’s Chandelier

给你一颗树,树的节点是以环状排布的(只能旋转,旋转同构),每个节点可以有1种颜色,问本质不同的树的个数 (颜色,结点数<=100)

环状计数可解决,关键是如何判断’旋转‘同构
把树用括号序列表示,让他字典序最小保证唯一。

#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (1000000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
ll pow2(ll a,ll b){
    if (b==1) return a;
    if (!b) return 1;
    ll c=pow2(a,b/2);
    c=mul(c,c);
    if (b&1) c=mul(c,a);
    return c; 
}
ll gcd(ll a,ll b){if (!b) return a;return gcd(b,a%b);}
#define MAXN (100+10)
int C;
struct Str{
    vector<int> e[MAXN];
    string s,ans;
    int len,tot;
    ll dp[MAXN];
    void mem() {
        len=s.size();
        For(i,tot) e[i].clear(),dp[i]=0;
        tot=0;
    }   
    int build(int &x) { 
        int now= ++tot;
        ++x;
        while (s[x]!=']'&&x<len) {
            e[now].pb(build(x));
            if (s[x]==',') ++x;
        }
        x++;
        return now;
    }
    string get_str(int x) {
        vector<string> tmp;
        int m=SI(e[x]);
        Rep(i,m) tmp.pb(get_str(e[x][i]));

        int tt=0;
        for(int i=1;i<=m;i++) {
            if (m%i==0) {
                bool flag=0;
                for(int j=0;j+i<m;j++) {
                    if (tmp[j]!=tmp[j+i]) {
                        flag=1;
                        break;
                    }
                }
                if (!flag) { 
                    tt=i; break;    
                }
            }
        }

        ll &an=dp[x] ;
        if (m==0) an=C;
        else {
            ll col=1;
            Rep(j,tt) {
                col = mul(col,dp[e[x][j]]);
            }
            an=0;
            For(i,m/tt) an=add(an,pow2(col,gcd(m/tt,i)));
            an=mul(an,pow2(m/tt,F-2)); 
            an=mul(an,C);
        }

        string ans;
        Rep(i,m) ans+=(tmp[i]);

        {
            For(i,m-1) {
                string t;
                Fork(j,i,m-1) t+=tmp[j];
                Rep(j,i) t+=tmp[j];
                if (t<ans) ans=t;
            }
        }
        return '['+ans +']';
    }
}t;
int main()
{
//  freopen("uva11540.in","r",stdin);

    int T=read();
    t.tot=0;
    For(kcase,T) {
        cin>>t.s>>C ;
        t.mem();
        int p;
        t.build(p=0);
        t.get_str(1);
        Pr(kcase,t.dp[1]);

    }
    return 0;
}

UVA 12387 Alphabet Soup

题意:已知一个圆,圆周上有P个点,已知点的位置,且其两两不同。请试图用S种颜色染色,问旋转同构数。

其实不用kmp也能过

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n) cout<<a[i]<<' '; cout<<endl; 
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
ll gcd(ll a,ll b){if (!b) return a; return gcd(b,a%b); }
ll pow2(ll a,ll b){
    if (b==1) return a;
    if (!b) return 1;
    ll c=pow2(a,b/2);
    c=mul(c,c);
    if (b&1) c=mul(c,a);
    return c; 
}
#define MAXN (1000000+10)
int a[MAXN],b[MAXN];
ll S,P;
int f[MAXN];
int main()
{
//  freopen("uva12387.in","r",stdin);
//  freopen(".out","w",stdout);

    while(cin>>S>>P) {
        if (S==-1) break;

        For(i,P) a[i]=read();
        sort(a+1,a+1+P);

        For(i,P-1) b[i]=a[i+1]-a[i];
        b[P]=a[1]-a[P]+360000;

        For(i,P) a[i]=a[i+P]=b[i+P]=b[i];


        f[1]=f[0]=0;
        Fork(i,2,2*P) {
            int p=f[i-1];
            while (p && a[p+1]!=a[i]) p=f[p];
            if (a[p+1]==a[i]) f[i] = p + 1;
            else f[i] = 0;
        }

        int t=f[P*2];
        while (P%(P*2-t)) t=f[t];
        t=P*2-t;

        S=pow2(S,t);
        ll ans=0;
        Rep(i,P/t) upd(ans,pow2(S,gcd(P/t,i)));
        ans=mul(ans,pow2(P/t,F-2));
        cout<<ans<<endl;
    }


    return 0;
}

UVA 1016/LA 2481 Silly Sort

题意:有一个长度为n的数列( n1000) ,每次交换2个数,代价是它们的和,问将数列排成严格升序的最小代价。

对于1个循环节,可以用循环节中最小那个数进行交换,
但是有时从某个地方“借”一个数来交换,用完还回去,更优。

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n) cout<<a[i]<<' '; cout<<endl; 
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (1000+10)
int a[MAXN],n,h[MAXN];
bool vis[MAXN];
pi p[MAXN];
int main()
{
//  freopen("la2481.in","r",stdin);
//  freopen(".out","w",stdout);
    int kcase=0;
    while(n=read())
    {
        For(i,n) {
            a[i]=read();
            p[i]=mp(a[i],i);
        }
        sort(p+1,p+1+n);
        MEM(vis)
        int mi=p[1].fi;
        ll ans=0; 
        For(i,n) {
            if (!vis[i]) {
                int len=0,mina=p[i].fi,sum=0,u=i;
                while (!vis[u]) {
                    vis[u]=1;
                    mina=min(mina,p[u].fi);
                    sum+=p[u].fi;
                    len++;
                    u=p[u].se;
                }
                if (len>1) {
                    ans+=min((len+1)*mi+mina+sum,(len-2)*mina+sum);
                }
            }
        }
        Pr(++kcase,ans);
        cout<<endl;
    }

    return 0;
}

UVA 11255 Necklace

题意:给3个颜色的珠子与其数量 (a+b+c40) ,让你用所有珠子串成项链,旋转翻转视为相等,问本质不同项链数?

参考Cubes 和 Arif in Dhaka (First Love Part 2)

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
#define MAXN (40+10)
#define MAXM (3+1)
int a[MAXM],b[MAXM],n;
const int m = 3;
ll C[MAXN][MAXN];
int gcd(int a,int b){if (!b) return a;return gcd(b,a%b);}
void init(int n) {
    C[0][0]=1;
    For(i,n) {
        C[i][0]=1;
        For(j,n) C[i][j]=C[i-1][j] + C[i-1][j-1]; 
    }
}
ll solve(int k) { //每k个一循环 
    int n=0;
    For(i,m) {
        if (a[i]%k) return 0;
        n+=a[i]/k;
    }
    ll ans=1;
    For(i,m) {
        ans *= C[n][a[i]/k];
        n-=a[i]/k;
    }
    return ans;
}
int main()
{
//  freopen("uva11255.in","r",stdin);
//  freopen(".out","w",stdout);
    init(40);
    int T = read();
    while (T--) {
        int n=0;
        For(i,m) n+=( a[i]=read() );

        ll ans= 0 ;
        Rep(i,n) ans+=solve(n/gcd(n,i));

        if (n%2==0) {
            For(i,m) For(j,m) {
                a[i]--; a[j]--;
                if (a[i]>=0 && a[j]>=0) ans+=n/2*solve(2);
                a[i]++; a[j]++;
            }
            ans+=n/2*solve(2);
        } else {
            For(i,m) {
                a[i]--; 
                if (a[i]>=0) ans+=n*solve(2);
                a[i]++; 
            }
        }


        printf("%lld\n",ans/2/n);
    } 



    return 0;
}

UVA 10733 The Colored Cubes

题意:给n种颜色对正方体六面任意染色,求能组成的本质不同的立方体个数

有24种置换,为了更好说明之前那个表,稍微修改了下:

情况置换个数
不动6(1)1
左转2(1)1(4)6
左转*22(1)2(2)3(3对面)
对顶点旋转左/右120度2(3)8(4对顶点*2方向)
对棱中点旋转180度3(2)6(6对棱)
合计24
#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair 
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n) cout<<a[i]<<' '; cout<<endl; 
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
    return x*f;
} 
ll pow2(ll a,ll b){
    ll p=1;
    For(i,b) p*=a;
    return p;
}
int main()
{
//  freopen("uva10733.in","r",stdin);
//  freopen(".out","w",stdout);
    ll n;
    while(cin>>n && n) {
        ll ans=pow2(n,6)+6*pow2(n,3)+3*pow2(n,4)+8*pow2(n,2)+6*pow2(n,3);
        cout<<ans/24<<endl;
    }


    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值