LCS HDU-5495
题意
给两个序列:({a_1,a_2,cdots,a_n}),({b_1,b_2,cdots,b_n}) ,都是 ({1,2,3,cdots,n }) 的一个排列。求出一个序列 (p) ,使得 (a_{p_1},a_{p_2},cdots,a_{p_n}) 和 (b_{p_1},b_{p_2},cdots,b_{p_n}) 的 ( ext{LCS}) 最大。输出该 ( ext{LCS}) 的值。
分析
对 (a_i->b_i) 建边,最终总能形成一个环,对于这个长度为 (L) 的环,我们总能找到一个长度为 (L-1) 的 ( ext{LCS})。所以,我们只要用序列的长度减去长度大于 (1) 的环的个数就是最终的结果。
代码
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N],nxt[N];
bool vis[N];
int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
int ans=0,b;
scanf("%d",&n);
for(int i=1;i<=n;i++)
vis[i]=0;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
{
scanf("%d",&b);
nxt[a[i]]=b;
}
for(int i=1;i<=n;i++)
{
if(!vis[a[i]])
{
int x=a[i],cnt=0;
while(!vis[x])
{
vis[x]=1;
x=nxt[x];
cnt++;
}
ans+=cnt;//cout<<"cnt="<<cnt<<endl;
if(cnt>1) ans--;
}
}
printf("%d
",ans);
}
return 0;
}
Count the Tetris HDU-1812
Let it Bead POJ-2409
题意
给出 (c) 种颜色的珍珠,每种的数量无限,组成长为 (s) 的项链。问可以组成多少种不同的项链。(csleq 32)
分析
Polya定理模板题,直接套公式。设 ({a_1,a_2,cdots,a_{|G|} }) 是 ({1,2,cdots,n}) 上的置换群,现用 (m) 种颜色对这 (n) 个点染色,则不同的染色方案有:
[ANS=frac{(m^{c_1}+m^{c_2}+cdots+m^{c_{|G|}})}{|G|}
]
其中,(c_k) 为置换 (a_k) 中轮换的个数,即循环节的个数。
常见置换的轮换个数:
- 旋转:(n) 个点顺时针旋转 (i) 个位置的置换,轮换的个数为:(gcd(i,n));
- 翻转:(n) 为偶数且对称轴不过顶点:(frac{n}{2}),(n) 为偶数且对称轴过顶点:(frac{n}{2}+1),(n) 为奇数:(frac{n+1}{2});
代码
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
ll power(ll a,int b)
{
ll res=1;
while(b)
{
if(b&1) res=res*a;
a=a*a;
b>>=1;
}
return res;
}
int main()
{
int c,s;
while(scanf("%d%d",&c,&s)!=EOF)
{
if(c==0&&s==0) break;
if(c==0||s==0) printf("0
");
ll ans=0;
int m=2*s;
for(int i=1;i<=s;i++)
ans+=power(1LL*c,gcd(i,s));
if(s&1)
ans+=1LL*s*power(1LL*c,(s+1)/2);
else
{
ans+=1LL*s/2*power(1LL*c,s/2);
ans+=1LL*s/2*power(1LL*c,s/2+1);
}
printf("%lld
",ans/m);
}
return 0;
}
Necklace of Beads POJ-1286
分析
模板题,同上。