【ContestHunter】【弱省胡策】【Round2】

官方题解:http://wyfcyx.is-programmer.com/posts/95490.html

A

  目前只会30分的暴力……DP好像很神的样子0.0(听说可以多次随机强行算?

 1 //Round2 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=110;
20 /*******************template********************/
21 int n,m;
22 double a[10][110];
23 
24 void work1(){
25     double ans=1.0;
26     F(i,1,m) ans*=(1.0-a[1][i]);
27     printf("%.9f
",1.0-ans);
28 }
29 void work2(){
30     double ans=0.0;
31     F(i,1,m) ans*=(1.0-a[1][i]);
32 }
33 int mp[10][110],my[N];
34 bool vis[N];
35 long double ans=0.0,gailv=1.0;
36 
37 bool go(int x){
38     F(i,1,m)
39         if (mp[x][i] && !vis[i]){
40             vis[i]=1;
41             if (!my[i]||go(my[i])){
42                 my[i]=x;
43                 return 1;
44             }
45         }
46     return 0;
47 }
48 void check(){
49 //    F(i,1,n){ F(j,1,m) printf("%d ",mp[i][j]); puts("");}
50     int tmp=0;
51     memset(my,0,sizeof my);
52     F(i,1,n){
53         memset(vis,0,sizeof vis);
54         if (go(i)) tmp++;
55     }
56     double gl=gailv;
57 //    printf("%d %.9f

",tmp,gl);
58     ans+=tmp*gailv;
59 }
60 void dfs(int x,int y){
61 //    printf("dfs %d %d
",x,y);
62     if (x==n+1){check();return;}
63     D(i,1,0){
64         mp[x][y]=i;
65         gailv*=i*a[x][y]+(1-i)*(1.0-a[x][y]);
66         if (y==m) dfs(x+1,1);
67         else dfs(x,y+1);
68         mp[x][y]=0;
69         gailv/=i*a[x][y]+(1-i)*(1.0-a[x][y]);
70     }
71 }
72 void work3(){
73     dfs(1,1);
74     double as=ans;
75     printf("%.9f
",as);
76 }
77 int main(){
78 #ifndef ONLINE_JUDGE
79     freopen("A.in","r",stdin);
80     freopen("A.out","w",stdout);
81 #endif
82     n=getint(); m=getint();
83     F(i,1,n) F(j,1,m) scanf("%lf",&a[i][j]);
84     if (n==1) work1();
85 //    else if (n==2) work2();
86     else 
87         work3();
88     return 0;
89 }
View Code(30分)

C

  原来是用FFT来做的好题!

  第一步用KMP比较简单,容易想到。

  这题的特点是每个字符都是0或1,所以考虑第二步的时候,可以用FFT来进行快速运算0.0太神了!利用卷积的特点,将一个串反转过来,然后相同的,会对答案贡献1,不同的贡献0,卷积一下就是两个串对应位置都是1的位数!太神奇了。。。(都是0的位数求法:整个异或一下,0变1,1变0)

  1 //Round2 C
  2 #include<cmath>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<iostream>
  7 #include<algorithm>
  8 #define rep(i,n) for(int i=0;i<n;++i)
  9 #define F(i,j,n) for(int i=j;i<=n;++i)
 10 #define D(i,j,n) for(int i=j;i>=n;--i)
 11 #define pb push_back
 12 using namespace std;
 13 typedef long long LL;
 14 inline int getint(){
 15     int r=1,v=0; char ch=getchar();
 16     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
 17     for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
 18     return r*v;
 19 }
 20 const int N=1000010;
 21 /*******************template********************/
 22 const double pi=acos(-1);
 23 struct comp{
 24     double r,i;
 25     comp(double r=0.0,double i=0.0):r(r),i(i){}
 26     comp operator * (const comp &b)const{return comp(r*b.r-i*b.i,r*b.i+i*b.r);}
 27     comp operator + (const comp &b)const{return comp(r+b.r,i+b.i);}
 28     comp operator - (const comp &b)const{return comp(r-b.r,i-b.i);}
 29 }A[N],B[N];
 30 
 31 int n,m,nxt[N],v[N],cnt,c[N],nn;
 32 char a[N][10],b[N][10],a2[N],b2[N];
 33 void FFT(comp *a,int n,int type){
 34     for(int i=0,j=0;i<n;++i){
 35         if (i<j) swap(a[i],a[j]);
 36         for(int k=n>>1;(j^=k)<k;k>>=1);
 37     }
 38     for(int m=1;m<n;m<<=1){
 39         double u=pi/m*type; comp wm(cos(u),sin(u));
 40         for(int i=0;i<n;i+=(m<<1)){
 41             comp w(1,0);
 42             rep(j,m){
 43                 comp &A=a[i+j+m],&B=a[i+j],t=w*A;
 44                 A=B-t; B=B+t; w=w*wm;
 45             }
 46         }
 47     }
 48     if (type==-1) rep(i,n) a[i].r/=n;
 49 }
 50 void KMP(){
 51     nxt[1]=nxt[2]=1;
 52     int j=1;
 53     F(i,2,m){
 54         while(j!=1 && strcmp(b[i],b[j])!=0) j=nxt[j];
 55         nxt[i+1]=strcmp(b[i],b[j])==0 ? ++j : 1;
 56     }
 57     j=1;
 58     F(i,1,n){
 59         while(j!=1 && strcmp(a[i],b[j])!=0) j=nxt[j];
 60         if (strcmp(a[i],b[j])==0) j++;
 61         if (j==m+1) v[++cnt]=i-m+1;
 62     }
 63 }
 64 void work(int x){
 65     rep(i,nn) A[i]=B[i]=comp(0,0);
 66     rep(i,n) if (a2[i+1]-'0'==x) A[i].r=1;
 67     rep(i,m) if (b2[i+1]-'0'==x) B[m-(i+1)].r=1;
 68     FFT(A,nn,1); FFT(B,nn,1);
 69     rep(i,nn) A[i]=A[i]*B[i];
 70     FFT(A,nn,-1);
 71     rep(i,n) c[i+1]+=(int)(A[i+m-1].r+0.5);
 72 }
 73 
 74 int main(){
 75 #ifndef ONLINE_JUDGE
 76     freopen("C.in","r",stdin);
 77     freopen("C.out","w",stdout);
 78 #endif
 79     n=getint(); m=getint();
 80     for(nn=1;nn<n+m-1;nn<<=1);
 81     F(i,1,n){
 82         scanf("%s",a[i]);
 83         a2[i]=a[i][7];
 84         a[i][7]='0';
 85     }
 86     F(i,1,m){
 87         scanf("%s",b[i]);
 88         b2[i]=b[i][7];
 89         b[i][7]='0';
 90     }
 91     KMP();
 92     if (cnt) puts("Yes");
 93     else {puts("No");return 0;}
 94     work(0);
 95     work(1);
 96     int ans1=1e9,ans2=0;
 97     F(i,1,cnt) if (m-c[v[i]]<ans1){
 98         ans1=m-c[v[i]]; ans2=v[i];
 99     }
100     printf("%d %d
",ans1,ans2);
101     return 0;
102 }
View Code
原文地址:https://www.cnblogs.com/Tunix/p/4549747.html