Codeforces Round #138 (Div. 1)

A

记得以前做过 当时好像没做对 就是找个子串 满足括号的匹配 []最多的

开两个栈模拟 标记下就行

 1 #include <iostream>

 2 #include<cstring>

 3 #include<algorithm>

 4 #include<cstdio>

 5 #include<stdlib.h>

 6 #include<cmath>

 7 #include<vector>

 8 #include<queue>

 9 #include<stack>

10 using namespace std;

11 #define N 100010

12 char s[N];

13 char st[N];

14 int sn[N][3];

15 int main()

16 {

17     int i,k,top=0;

18     cin>>s;

19     k = strlen(s);

20     sn[0][0] = -1;sn[0][2] = -1;

21     for(i = 0 ;i < k ;i++)

22     {

23         if(s[i]=='('||s[i]=='[')

24          {

25              st[++top] = s[i];

26              sn[top][0] = i;

27              sn[top][1] = 0;

28              sn[top][2] = i;

29          }

30         else

31         {

32             if(s[i]==')')

33             {

34                 if(top&&st[top]=='(')

35                 {

36                    top--;

37                    sn[top][1] += sn[top+1][1];

38                    sn[top][2] = i;

39                 }

40                 else

41                 {

42                     st[++top] = s[i];

43                     sn[top][0] = i;

44                     sn[top][1] = 0;

45                     sn[top][2] = i;

46                 }

47             }

48             else

49             {

50                 if(top&&st[top]=='[')

51                 {

52                    top--;

53                    sn[top][1] += sn[top+1][1]+1;

54                    sn[top][2] = i;

55                 }

56                 else

57                 {

58                     st[++top] = s[i];

59                     sn[top][0] = i;

60                     sn[top][1] = 0;

61                     sn[top][2] = i;

62                 }

63             }

64         }

65     }

66     int maxz=0,x=0;

67     for(i = 0 ; i <= top ; i++)

68     {

69         if(maxz<sn[i][1])

70         {

71             maxz = sn[i][1];

72             x = i;

73         }

74     }

75     cout<<maxz<<endl;

76     for(i = sn[x][0]+1 ; i <= sn[x][2] ; i++)

77     cout<<s[i];

78     puts("");

79     return 0;

80 }
View Code

这题。。描述的很抽象。 按我的话来说 就是对于每一个s[i]总能找到一个子串包含它 而且与t串相等 t串还必须包含了s串的所有字母

做法:开个标记数组 标记每个字母向前以及向后最大的匹配位置 是否大于等于t串的长度

 1 #include <iostream>

 2 #include<cstring>

 3 #include<algorithm>

 4 #include<cstdio>

 5 #include<stdlib.h>

 6 #include<cmath>

 7 #include<vector>

 8 #include<queue>

 9 #include<stack>

10 using namespace std;

11 #define N 200010

12 char s[N],t[N];

13 int o[N],f[27],w[N];

14 int main()

15 {

16     int i,j,k,tk;

17     while(cin>>s)

18     {

19         memset(o,0,sizeof(o));

20         memset(w,0,sizeof(w));

21         memset(f,0,sizeof(f));

22         k = strlen(s);

23         cin>>t;

24         tk = strlen(t);

25         for(i = tk-1 ; i >= 0 ; i--)

26         {

27             f[t[i]-'a'] = 1;

28         }

29         for(i = k-1 ; i >= 0 ; i--)

30         {

31             if(!f[s[i]-'a']) break;

32         }

33         if(i!=-1||s[0]!=t[0])

34         {

35             puts("No");

36             continue;

37         }

38         j = 0 ;

39         for(i = 0 ; i < k ;i++)

40         {

41             if(s[i]==t[j])

42             {

43                 j++;

44                 o[i] = j;

45                 f[s[i]-'a'] = j;

46             }

47             else

48             {

49                 o[i] = f[s[i]-'a'];

50             }

51         }

52         memset(f,0,sizeof(f));

53         j = tk-1;

54         for(i = k-1 ; i >=0 ;i--)

55         {

56             if(s[i]==t[j])

57             {

58                 j--;

59                 w[i] = tk-1-j;

60                 f[s[i]-'a'] = tk-1-j;

61             }

62             else

63             {

64                 w[i] = f[s[i]-'a'];

65             }

66         }

67         for(i = 0 ; i < k ;i++)

68         {

69             if(o[i]+w[i]<=tk) break;

70             //cout<<o[i]<<" "<<w[i]<<endl;

71         }

72         if(i==k)

73         puts("Yes");

74         else  puts("No");

75     }

76     return 0;

77 }
View Code

 C 数论题

无奈数论太差 研究题解研究了好久。。可以推公式 我把具体的推法写一下 具体公式是对于第i个数来说 k次转换的结果 是 c(k+j-1,j)个a[j]之和 (j<=i) 就是当前的数 是由多个个a[j]组成的

比如 a[i]都为1  n为5 吧  初始为 1 1 1 1 1

就可以推了 k=1时  第一个数  1     =1           k = 2  第一个数  1     =1                                 ===》 1

         第二个数   1 1 (代表1个a[1] 1个a[j]) =2                 第二个数   2 1          (代表2个a[1] 1个a[j]) =3      ===》  3 1

         第三个数   1 1 1          = 3      +(2,1)  ===>            第三个数   3 2 1          = 6                                ===》  6 3 1

         第四个数 1 1 1 1        = 4      +(3,2,1) ====>        第四个数 4 3 2 1        = 10                                  ====》 10 6 3 1

         第五个数   1 1 1 1 1      =5      +(4,3,2,1)====>      第五个数   5 4 3 2 1     = 15                                =====》  15 10 6 3 1  

差不多基本可以看下了 题解说可以看出规律为。。。 说实话我没看出来。。。  不过我验证了它的规律。。。 对于k此操作 对应的用去a[j]的个数 为o[j] = c(k+j-1,j);

注意这里不要用反  例如上面最后一组 是15个a[0] 10个a[1]..1个a[4]  

另外一些数论的知识 因为涉及到组合数 又涉及到取余 所以涉及到了逆元  对于除法的逆元  a/b = ab^-1%mod   b^-1为其逆元 

逆元又涉及到一递推公式  i的逆元 nv[i]=(-MOD/i*nv[MOD%i]);    验证:两边同乘i nv[i]*i = (-mod/i*nv[mod%i])*i;     逆元性质 a*nv[a]%MOD=1 1 = (-mod/i)*i*1/(mod%i)

so i*(-MOD/i) == (MOD%i)%MOD 

-(MOD-MOD%i) == (MOD%i)%MOD  这个式子显然成立  证完

 1 #include <iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<algorithm>

 5 #include<stdlib.h>

 6 #include<vector>

 7 #include<cmath>

 8 #include<queue>

 9 #include<set>

10 using namespace std;

11 #define N 2010

12 const double eps = 1e-8;

13 const double pi = acos(-1.0);

14 const double inf = ~0u>>2;

15 #define LL long long

16 #define mod 1000000007

17 LL a[N],v[N],o[N];

18 LL cn(int n,int m)

19 {

20     int i;

21     LL s = 1;

22     for(i = 1 ; i <= m ;i++)

23     {

24         s = ((s*v[i])%mod*(n-i+1))%mod;//除法取余 乘其逆元

25     }

26     return s;

27 }

28 int main()

29 {

30     int i,j,n,k;

31     cin>>n>>k;

32     for(i = 0; i < n ; i++)

33     cin>>a[i];

34     if(k==0)

35     {

36         for(i = 0 ; i< n ;i++)

37         cout<<a[i]<<" ";

38         puts("");

39         return 0;

40     }

41     v[0] = v[1] = 1;

42     for(i = 2; i < n ; i++)

43     v[i] = ((-mod/i*v[mod%i])%mod+mod)%mod;

44     for(i = 0 ; i < n ;i++)

45     {

46         o[i] = cn(i+k-1,i);

47     }

48     for(i = 0 ; i < n; i++)

49     {

50         LL ans=0;

51         for(j = 0 ;  j <= i ; j++)

52         ans=(ans+a[j]*o[i-j])%mod;

53         cout<<ans<<" ";

54     }

55     puts("");

56     return 0;

57 }
View Code

 

 

你可能感兴趣的:(codeforces)