嘛,一直以来蒟蒻都没怎么打过CF……现在还是蓝名狗……今天跟着zyf打了一场virtual,果断一题滚粗aaarticlea/jpeg;base64,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" alt="" />
Kyoya and Colored Balls
签到题,从前往后考虑,第$i$种球的最后一个一定要放在当前序列的最后一个位置,剩下的$a[i]-1$个可以在前面随便放……所以$ans=\prod_{i=2}^n \binom{s[i]-1}{a[i]-1} $
//Codeforces #309 A
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
typedef long long LL;
inline int getint(){
int r=,v=; char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-;
for(; isdigit(ch);ch=getchar()) v=v*-''+ch;
return r*v;
}
const int N=,P=;
/*******************template********************/
LL n,a[N],s[N];
LL sum,ans=,fac[N],inv[N];
LL Pow(LL a,int b){
LL r=;
for(;b;b>>=,a=a*a%P) if (b&) r=r*a%P;
return r;
}
LL C(int n,int m){ return fac[n]*inv[m]%P*inv[n-m]%P;}
int main(){
#ifndef ONLINE_JUDGE
freopen("A.in","r",stdin);
freopen("A.out","w",stdout);
#endif
n=getint();
fac[]=fac[]=;
F(i,,) fac[i]=fac[i-]*i%P;
inv[]=Pow(fac[],P-); inv[]=;
D(i,,) inv[i]=inv[i+]*(i+)%P; F(i,,n) a[i]=getint(),s[i]=(s[i-]+a[i])%P;
ans=;
F(i,,n) ans=ans*C(s[i]-,a[i]-)%P;
cout <<ans<<endl;
return ;
}
Kyoya and Permutation
这题……其实我在考试的时候想出正解了……然而忘了 k 会爆int(一开始还记得,过了N久想出答案的时候早忘了……QAQ)所以一直没过……
我的思考过程:
随便手写几个置换会发现,满足条件的排列,分解成循环的时候,循环长度不会超过2,且只能相邻两个交换。再考虑字典序的问题,我一开始没找到规律……就拿二进制数表示循环,比如:
1 2 3 4 6 5
0 0 0 0 0 1
1 2 4 3 6 5
0 0 0 1 0 1
也就是说,某一位是1就代表着这一位与前一位的数进行交换,那么明显有:不能出现相邻的1。那么如何数方案数呢?我yy了这样一个DP:
$g[i]$表示倒数第$i$位是1,且前面都是0的方案数。
$s[i]$表示只考虑后$i$位的总方案数。
那么有:$g[i]=s[i-2]+1$ $s[i]=s[i-1]+g[i]$
(其实g[i]是fib数列,我这样搞麻烦了……因为明显有g[i]=g[i-1]+g[i-2],为什么呢?我们将$i-1$的那些方案的最左边的1左移一位,就得到了$i$的一部分方案,$i-2$的应该不用我说了……)
然后利用$s[i]$从大往小找是第几个就可以了,自己想一会儿就可以想出来……然而我WA以后一直以为是这里没想对,没考虑到是$k$爆int的缘故QAQ
//Codeforces #309 B
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
typedef long long LL;
inline LL getint(){
LL r=,v=; char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-;
for(; isdigit(ch);ch=getchar()) v=v*-''+ch;
return r*v;
}
const int N=;
/*******************template********************/ int a[N];
LL n,k,f[N],g[N],s[N];
int main(){
#ifndef ONLINE_JUDGE
freopen("B.in","r",stdin);
freopen("B.out","w",stdout);
#endif
n=getint(); k=getint()-;
F(i,,n) a[i]=i;
g[]=s[]=; g[]=; s[]=;
F(i,,n){
g[i]=s[i-]+;
s[i]=s[i-]+g[i];
}
D(i,n-,)
if (k<=s[i] && k>s[i-]){
swap(a[n-i+],a[n-i]);
k=k-s[i-]-;
}
F(i,,n-) printf("%d ",a[i]);
printf("%d\n",a[n]);
return ;
}
Love Triangles
三角恋什么鬼= =
Orz zyf
题目中的条件是说:任意三个人之间,要么是彼此都喜欢,要么是只有其中两个人互相喜欢,另一个人讨厌他们两个。
这样我们会发现:如果A喜欢B,B喜欢C,那么A一定喜欢C。(废话)(然而我并没有想到sad),并且最后结果一定是1或2个连通块(不存在三个人互相都不喜欢)
所以就是将互相喜欢的进行缩点,不喜欢的关系互相连边,然后进行黑白染色,如果不喜欢关系出现环且推出这个人既黑又白那么无解……
//Codeforces #309 C
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
typedef long long LL;
inline int getint(){
int r=,v=; char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-;
for(; isdigit(ch);ch=getchar()) v=v*-''+ch;
return r*v;
}
const int N=,P=;
/*******************template********************/
int head[N],nxt[N<<],to[N<<],cnt;
void add(int x,int y){
to[++cnt]=y; nxt[cnt]=head[x]; head[x]=cnt;
to[++cnt]=x; nxt[cnt]=head[y]; head[y]=cnt;
} int n,m;
int fa[N],color[N];
inline int getf(int x){return fa[x]==x ? x : fa[x]=getf(fa[x]);}
struct ques{int x,y,z;}q[N];
bool operator < (ques a,ques b){return a.z>b.z;}
bool flag,v[N];
void dfs(int x,int cl){
v[x]=; color[x]=cl;
for(int i=head[x];i;i=nxt[i])
if (!v[to[i]]) dfs(to[i],-cl);
else if (color[to[i]]!=-cl) flag=;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("C.in","r",stdin);
freopen("C.out","w",stdout);
#endif
n=getint(); m=getint();
F(i,,n) fa[i]=i;
F(i,,m) q[i].x=getint(),q[i].y=getint(),q[i].z=getint();
sort(q+,q+m+);
F(i,,m){
int f1=getf(q[i].x),f2=getf(q[i].y);
if (q[i].z){
if (f1!=f2) fa[f1]=f2;
}else add(f1,f2);
}
LL ans=;
F(i,,n) if (getf(i)==i && !v[i]){
ans=ans*%P;
dfs(i,);
}
ans=ans*%P;
if (flag) puts("");
else cout <<ans<<endl;
return ;
}