UVA 10294 Arif in Dhaka (First Love Part 2)
一个n个珠子的环形首饰,每个珠子可能的颜色有t种。
考虑旋转,考虑旋转和翻转,分别有几种本质不同的首饰。
考虑旋转有n种,若逆时针旋转i颗珠子,则 i,2i,3i 构成循环,这个循环有 n/gcd(i,n) 个元素,共有 gcd(i,n) 个循环,置换的不同点个数为 ∑n−1i=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
,求置换
找规律:
倒推,对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 |
左转*2 | 6(2) | 3 |
左转,上转 | 4(3) | 8 |
左转,上转*2 | 2(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的数列( n≤1000) ,每次交换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+c≤40) ,让你用所有珠子串成项链,旋转翻转视为相等,问本质不同项链数?
参考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 |
左转*2 | 2(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;
}