【Codeforces】【#295】【Div.1】
嘛,一直以来蒟蒻都没怎么打过CF……现在还是蓝名狗……今天跟着zyf打了一场virtual,果断一题滚粗
Kyoya and Colored Balls
签到题,从前往后考虑,第$i$种球的最后一个一定要放在当前序列的最后一个位置,剩下的$a[i]-1$个可以在前面随便放……所以$ans=\prod_{i=2}^n \binom{s[i]-1}{a[i]-1} $
1 //Codeforces #309 A 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<iostream> 6 #include<algorithm> 7 #define rep(i,n) for(int i=0;i<n;++i) 8 #define F(i,j,n) for(int i=j;i<=n;++i) 9 #define D(i,j,n) for(int i=j;i>=n;--i) 10 #define pb push_back 11 using namespace std; 12 typedef long long LL; 13 inline int getint(){ 14 int r=1,v=0; char ch=getchar(); 15 for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1; 16 for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch; 17 return r*v; 18 } 19 const int N=100010,P=1000000007; 20 /*******************template********************/ 21 LL n,a[N],s[N]; 22 LL sum,ans=1,fac[N],inv[N]; 23 LL Pow(LL a,int b){ 24 LL r=1; 25 for(;b;b>>=1,a=a*a%P) if (b&1) r=r*a%P; 26 return r; 27 } 28 LL C(int n,int m){ return fac[n]*inv[m]%P*inv[n-m]%P;} 29 int main(){ 30 #ifndef ONLINE_JUDGE 31 freopen("A.in","r",stdin); 32 freopen("A.out","w",stdout); 33 #endif 34 n=getint(); 35 fac[0]=fac[1]=1; 36 F(i,1,1000) fac[i]=fac[i-1]*i%P; 37 inv[1000]=Pow(fac[1000],P-2); inv[0]=1; 38 D(i,999,1) inv[i]=inv[i+1]*(i+1)%P; 39 40 F(i,1,n) a[i]=getint(),s[i]=(s[i-1]+a[i])%P; 41 ans=1; 42 F(i,2,n) ans=ans*C(s[i]-1,a[i]-1)%P; 43 cout <<ans<<endl; 44 return 0; 45 }
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
1 //Codeforces #309 B 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<iostream> 6 #include<algorithm> 7 #define rep(i,n) for(int i=0;i<n;++i) 8 #define F(i,j,n) for(int i=j;i<=n;++i) 9 #define D(i,j,n) for(int i=j;i>=n;--i) 10 #define pb push_back 11 using namespace std; 12 typedef long long LL; 13 inline LL getint(){ 14 LL r=1,v=0; char ch=getchar(); 15 for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1; 16 for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch; 17 return r*v; 18 } 19 const int N=100010; 20 /*******************template********************/ 21 22 int a[N]; 23 LL n,k,f[N],g[N],s[N]; 24 int main(){ 25 #ifndef ONLINE_JUDGE 26 freopen("B.in","r",stdin); 27 freopen("B.out","w",stdout); 28 #endif 29 n=getint(); k=getint()-1; 30 F(i,1,n) a[i]=i; 31 g[1]=s[1]=1; g[2]=1; s[2]=2; 32 F(i,2,n){ 33 g[i]=s[i-2]+1; 34 s[i]=s[i-1]+g[i]; 35 } 36 D(i,n-1,1) 37 if (k<=s[i] && k>s[i-1]){ 38 swap(a[n-i+1],a[n-i]); 39 k=k-s[i-1]-1; 40 } 41 F(i,1,n-1) printf("%d ",a[i]); 42 printf("%d\n",a[n]); 43 return 0; 44 }
Love Triangles
三角恋什么鬼= =
Orz zyf
题目中的条件是说:任意三个人之间,要么是彼此都喜欢,要么是只有其中两个人互相喜欢,另一个人讨厌他们两个。
这样我们会发现:如果A喜欢B,B喜欢C,那么A一定喜欢C。(废话)(然而我并没有想到sad),并且最后结果一定是1或2个连通块(不存在三个人互相都不喜欢)
所以就是将互相喜欢的进行缩点,不喜欢的关系互相连边,然后进行黑白染色,如果不喜欢关系出现环且推出这个人既黑又白那么无解……
1 //Codeforces #309 C 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<iostream> 6 #include<algorithm> 7 #define rep(i,n) for(int i=0;i<n;++i) 8 #define F(i,j,n) for(int i=j;i<=n;++i) 9 #define D(i,j,n) for(int i=j;i>=n;--i) 10 #define pb push_back 11 using namespace std; 12 typedef long long LL; 13 inline int getint(){ 14 int r=1,v=0; char ch=getchar(); 15 for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1; 16 for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch; 17 return r*v; 18 } 19 const int N=100010,P=1000000007; 20 /*******************template********************/ 21 int head[N],nxt[N<<1],to[N<<1],cnt; 22 void add(int x,int y){ 23 to[++cnt]=y; nxt[cnt]=head[x]; head[x]=cnt; 24 to[++cnt]=x; nxt[cnt]=head[y]; head[y]=cnt; 25 } 26 27 int n,m; 28 int fa[N],color[N]; 29 inline int getf(int x){return fa[x]==x ? x : fa[x]=getf(fa[x]);} 30 struct ques{int x,y,z;}q[N]; 31 bool operator < (ques a,ques b){return a.z>b.z;} 32 bool flag,v[N]; 33 void dfs(int x,int cl){ 34 v[x]=1; color[x]=cl; 35 for(int i=head[x];i;i=nxt[i]) 36 if (!v[to[i]]) dfs(to[i],1-cl); 37 else if (color[to[i]]!=1-cl) flag=1; 38 } 39 int main(){ 40 #ifndef ONLINE_JUDGE 41 freopen("C.in","r",stdin); 42 freopen("C.out","w",stdout); 43 #endif 44 n=getint(); m=getint(); 45 F(i,1,n) fa[i]=i; 46 F(i,1,m) q[i].x=getint(),q[i].y=getint(),q[i].z=getint(); 47 sort(q+1,q+m+1); 48 F(i,1,m){ 49 int f1=getf(q[i].x),f2=getf(q[i].y); 50 if (q[i].z){ 51 if (f1!=f2) fa[f1]=f2; 52 }else add(f1,f2); 53 } 54 LL ans=1; 55 F(i,1,n) if (getf(i)==i && !v[i]){ 56 ans=ans*2%P; 57 dfs(i,0); 58 } 59 ans=ans*500000004%P; 60 if (flag) puts("0"); 61 else cout <<ans<<endl; 62 return 0; 63 }