【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 }
View Code

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 }
View Code

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 }
View Code

 

posted @ 2015-06-25 16:08  Tunix  阅读(...)  评论(...编辑  收藏