zoukankan      html  css  js  c++  java
  • 7月29集训训练个人赛第五场

    A Codeforces 126B

    KMP。直接计算next数组就可以了,然后按照next数组的值直接判定是否存在一个子串长度满足条件即可。

     

     1 #include <stdio.h>
     2 #include <string.h>
     3 const int maxn = 1000005;
     4 char src[maxn];
     5 int f[maxn];
     6 
     7 void getFail(char *src){
     8     f[1] = 0;
     9     int cur = 0;
    10     for(int i = 2; src[i]; i ++){
    11         while(src[cur + 1] != src[i] && cur) cur = f[cur];
    12         if(src[cur + 1]==src[i]) f[i] = ++ cur;
    13         else f[i] = cur = 0;
    14     }
    15 }
    16 bool check(int len){
    17     int x = 0;
    18     for(int i = 1; src[i]; i ++){
    19         x = x + (f[i] >= len);
    20     }
    21     if(x < 2) return false;
    22     return true;
    23 }
    24 int main(){
    25     //freopen("test.in", "r", stdin);
    26     for(;scanf("%s", src + 1)!=EOF;){
    27         memset(f, 0, sizeof(f));
    28         getFail(src);
    29         int len = strlen(src+1);
    30         int ans = f[len];
    31         if(ans == 0){
    32                     printf("Just a legend
    ");
    33                     continue;
    34         }
    35         if(len%(len - ans) == 0 && (len/(len - ans) > 2)){
    36             for(int i = 1; i <= len - 2*(len - ans); i ++)
    37                 putchar(src[i]);
    38             putchar('
    ');
    39             continue;
    40         }
    41 
    42         for(;!check(ans) && ans; ans = f[ans]);
    43         if(ans == 0){
    44             printf("Just a legend
    ");
    45         }
    46         else{
    47             for(int i = 1; i <= ans; i ++){
    48                 putchar(src[i]);
    49             }
    50             putchar('
    ');
    51         }
    52     }
    53     return 0;
    54 }
    View Code

    B Codeforces 315E

    树状数组或者线段树。问题是统计序列的每个子序列的要写的序列的个数。直接看代码吧,表示已经不晓得怎么解释了。或者去看官方题解好了。。http://codeforces.com/blog/entry/7905

     

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 using namespace std;
     5 #define MOD 1000000007
     6 const int maxn = 1000005;
     7 typedef long long LL;
     8 LL A[maxn], B[maxn];
     9 
    10 #define LOWBIT(x) ((x)&(-x))
    11 void add(int x, LL y){
    12     while(x < maxn){
    13         A[x] = (A[x] + y)%MOD;
    14         x += LOWBIT(x);
    15     }
    16 }
    17 LL getSum(int x){
    18     LL sum = 0;
    19     while(x){
    20         sum = (sum + A[x])%MOD;
    21         x -= LOWBIT(x);
    22     }
    23     return sum%MOD;
    24 }
    25 int main(){
    26     int n, x;
    27     cin>>n;
    28     LL ans = 0;
    29     for(int i = 1; i <= n; i ++){
    30         cin>>x;
    31         LL cur = getSum(x);
    32         cur = (cur*x+x)%MOD;
    33         ans = (ans + cur - B[x])%MOD;
    34         add(x, cur - B[x]);
    35         B[x] = cur;
    36     }
    37     cout<<(ans%MOD+MOD)%MOD<<endl;
    38     return 0;
    39 }
    View Code

    C Codeforces 242E

    线段树的裸题。可以将和拆分成二进制位计算就可以了,剩余的就是赤果果的线段树了。

     

      1 #include <stdio.h>
      2 #include <string.h>
      3 typedef long long LL;
      4 const int maxn = 100005;
      5 const int SIZE = 21;
      6 
      7 #define lson(c) (c<<1)
      8 #define rson(c) (c<<1|1)
      9 #define mid(l, r) ((l+r)/2)
     10 
     11 struct Tree{
     12     int f[maxn*4][SIZE];
     13     int s[maxn*4];
     14     void push_up(int c){
     15         int l = lson(c);
     16         int r = rson(c);
     17         for(int i = 0; i < SIZE; i ++){
     18             f[c][i] = f[l][i] + f[r][i];
     19         }
     20         s[c] = 0;
     21     }
     22     void push_down(int c, int l, int r){
     23         int ls = lson(c);
     24         int rs = rson(c);
     25         int t = s[c];
     26         int md = mid(l, r);
     27         if(s[c]==0) return;
     28 
     29         for(int i = 0; i < SIZE; i ++, t >>= 1){
     30             if(t&1){
     31                 f[ls][i] = (md - l + 1) - f[ls][i];
     32                 f[rs][i] = (r - md) - f[rs][i];
     33             }
     34         }
     35                 s[ls]^=s[c];
     36                 s[rs]^=s[c];
     37     }
     38     void build(int c, int l, int r){
     39         s[c] = 0;
     40         if(l==r){
     41             int x; scanf("%d", &x);
     42             for(int i = 0; i < SIZE; i ++){
     43                 f[c][i] = x&1; x>>=1;
     44             }
     45             return;
     46         }
     47         build(lson(c), l, mid(l, r));
     48         build(rson(c), mid(l, r) + 1, r);
     49         push_up(c);
     50     }
     51     void update(int c, int l, int r, int lp, int rp, int x){
     52         if(lp <= l && rp >= r){
     53             s[c] ^= x;
     54             for(int i = 0; i < SIZE; i ++, x>>=1){
     55                 if(x&1) f[c][i] = (r - l + 1) - f[c][i];
     56             }
     57             return ;
     58         }
     59         push_down(c, l, r);
     60         int md = mid(l, r);
     61         if(rp <= md) update(lson(c), l, md, lp, rp, x);
     62         else if(lp > md) update(rson(c), md + 1, r, lp, rp, x);
     63         else{
     64             update(lson(c), l, md, lp, md, x);
     65             update(rson(c), md + 1, r, md + 1, rp, x);
     66         }
     67         push_up(c);
     68     }
     69     void query(int c, int l, int r, int lp, int rp, int ans[]){
     70         if(lp <= l && rp >= r){
     71             for(int i = 0; i < SIZE; i ++){
     72                 ans[i] += f[c][i];
     73             }
     74             return;
     75         }
     76         push_down(c, l, r);
     77         int md = mid(l, r);
     78         if(rp <= md) query(lson(c), l, md, lp, rp, ans);
     79         else if(lp > md) query(rson(c), md + 1, r, lp, rp, ans);
     80         else{
     81             query(lson(c), l, md, lp, md, ans);
     82             query(rson(c), md + 1, r, md + 1, rp, ans);
     83         }
     84         push_up(c);
     85     }
     86 }tree;
     87 
     88 int main(){
     89     //freopen("test.in", "r", stdin);
     90     for(int n, m; scanf("%d", &n)!=EOF;){
     91         tree.build(1, 1, n);
     92         int ans[32];
     93         scanf("%d", &m);
     94         for(int i = 1, l, r, t; i <= m; i ++){
     95             scanf("%d%d%d", &t, &l, &r);
     96             if(t==1){
     97                 memset(ans, 0, sizeof(ans));
     98                 tree.query(1, 1, n, l, r, ans);
     99                 LL answer = 0;
    100                 for(int i = 0, x = 1; i < SIZE; i ++){
    101                     answer = answer + (LL)x * ans[i];
    102                     x<<=1;
    103                 }
    104                 printf("%I64d
    ", answer);
    105             }
    106             else{
    107                 int x;
    108                 scanf("%d", &x);
    109                 tree.update(1, 1, n, l, r, x);
    110             }
    111         }
    112     }
    113     return 0;
    114 }
    View Code

    D Codeforces 11D

    状态压缩,dp[mask][i]表示遍历mask中的所有点并以最小标号的点为起点,以i点为终点的简单路径的个数。集合与路径上的动态规划http://codeforces.com/blog/entry/337

     

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 using namespace std;
     5 const int maxn = 20;
     6 typedef long long LL;
     7 int g[maxn][maxn];
     8 LL d[1<<maxn][maxn];
     9 LL ans;
    10 
    11 inline bool bit(int i, int mask){
    12     return mask&(1<<i);
    13 }
    14 inline int first(int mask){
    15     int r;
    16     for(r = 0; !(mask &(1<<r)); r ++);
    17     return r;
    18 }
    19 inline int count(int mask){
    20     int c = 0;
    21     for(; mask; mask>>=1){
    22         c += (mask&1);
    23     }
    24     return c;
    25 }
    26 LL dfs(int mask, int ep, int n){
    27     int cnt = count(mask), sp = first(mask); LL sum = 0;
    28     if(d[mask][ep]>=0) return d[mask][ep];
    29     for(int p = first(mask); p < n; p ++){
    30         if(p != ep && bit(p, mask) && g[p][ep] && (cnt==2||p != sp)){
    31             sum = sum + dfs(mask^(1<<ep), p, n);
    32         }
    33     }
    34     if(cnt > 2 && g[ep][sp])
    35         ans += sum;
    36     return (d[mask][ep] = sum);
    37 }
    38 int main(){
    39     //freopen("test.in", "r", stdin);
    40     for(int n, m; scanf("%d%d", &n, &m)!=EOF; ){
    41         memset(g, 0, sizeof(g));
    42         memset(d, -1, sizeof(d));
    43         for(int i = 1, x, y; i <= m; i ++){
    44             scanf("%d%d", &x, &y);
    45             x --, y --;
    46             g[x][y] = g[y][x] = 1;
    47         }
    48         int mask = 1<<n;
    49         ans = 0;
    50         for(int i = 0; i < n; i ++)
    51             d[1<<i][i] = 1;
    52         for(int i = 1; i < mask; i ++){
    53             if(count(i)>1){
    54                 int sp = first(i);
    55                 for(int j = sp; j < n; j ++){
    56                     if(bit(j, i) && g[sp][j]){
    57                         dfs(i, j, n);
    58                     }
    59                 }
    60             }
    61         }
    62         printf("%I64d
    ", ans/2);
    63     }
    64 
    65     return 0;
    66 }
    View Code

    E POJ 1285

    水题。求多重组合,母函数或者DP搞。母函数就很直接了,每一种选取的个数为0-a[i],所以直接套模板就是了。母函数的相关资料: http://www.wutianqi.com/?p=596

    DPdp[i][j]表示从前i重物品中选取j件的表示方法,所以dp[i][j] = sigma(dp[i-1][j-x]) 其中x <= a[i],a[i]表示第i件物品的个数。

     

     1 #include <stdio.h>
     2 #include <string.h>
     3 typedef long long LL;
     4 int cnt[55];
     5 LL A[55], B[55];
     6 
     7 int findNext(int c){
     8     for(int i = c + 1; i <= 51; i ++){
     9         if(cnt[i]) return i;
    10     }
    11     return -1;
    12 }
    13 
    14 void process(){
    15     memset(A, 0, sizeof(A));
    16     memset(B, 0, sizeof(B));
    17     int c, r = 0;
    18     c = findNext(0);
    19     for(int i = 0; i <= cnt[c]; i ++){
    20         A[i] = 1;
    21     }
    22     r = cnt[c];
    23     while((c = findNext(c))!=-1){
    24         for(int i = 0; i <= r; i ++){
    25             for(int j = 0; j <= cnt[c]; j ++){
    26                 B[i+j] += A[i];
    27             }
    28         }
    29         r += cnt[c];
    30         for(int i = 0; i <= r; i ++){
    31             A[i] = B[i], B[i] = 0;
    32         }
    33     }
    34 }
    35 
    36 int main(){
    37     int n, m;
    38     for(int kcas = 1;scanf("%d%d", &n, &m)!=EOF, n||m; kcas ++){
    39         memset(cnt, 0, sizeof(cnt));
    40         for(int i = 1; i <= n; i ++){
    41             int d; scanf("%d", &d);
    42             cnt[d] ++;
    43         }
    44         process();
    45         printf("Case %d:
    ", kcas);
    46         for(int i = 1; i <= m; i ++){
    47             int d; scanf("%d", &d);
    48             printf("%I64d
    ", A[d]);
    49         }
    50     }
    51     return 0;
    52 }
    View Code

    F Codeforces 146E

    DP 首先考虑到为lucky的数字只有1300多个,这样就可以DP了。首先统计出不同lucky数字的个数,以及每个lucky出现的次数,排个序,然后dp[i][j]表示从前ilucky数中选取j个的选择办法, dp[i][j] = dp[i-1][j] + c[i] * dp[i-1][j-1],其中c[i]表示第ilucky出现的次数。然后枚举选择lucky数的个数,答案就是sigma(dp[l][x] * C[s][k-x]),其中l表示lucky数的不同个数,s表示非lucky数的个数。

     

     1 #include <stdio.h>
     2 #include <map>
     3 #include <string.h>
     4 #include <algorithm>
     5 using namespace std;
     6 #define maxn 1500
     7 typedef long long LL;
     8 const LL mod = 1000000007;
     9 LL dp[maxn][maxn], C[100005];
    10 map<int, int> hash;
    11 
    12 bool check(int a){
    13     for(;a; a/=10){
    14         if(a%10!=4&&a%10!=7) return false;
    15     }
    16     return true;
    17 }
    18 
    19 void extgcd(LL a, LL b, LL&g, LL&x, LL&y){
    20     if(b==0){
    21         g = a, x = 1, y = 0; return;
    22     }
    23     extgcd(b, a%b, g, y, x);
    24     y -= a/b*x;
    25 }
    26 
    27 LL inv(LL a){
    28     LL g, x, y;
    29     extgcd(a, mod, g, x, y);
    30     return (x + mod)%mod;
    31 }
    32 int main(){
    33     for(int n, k; scanf("%d%d", &n, &k)!=EOF; ){
    34         hash.clear();
    35         int nl = 0, nu = 0;
    36         for(int i = 1, x; i <= n; i ++){
    37             scanf("%d", &x);
    38             if(check(x)) {
    39                 if(hash.count(x)==0){
    40                     hash.insert(make_pair(x, 1));
    41                     nl ++;
    42                 }
    43                 else hash[x] ++;
    44             }
    45             else nu ++;
    46         }
    47         dp[0][0] = 1;
    48         int l = 1;
    49         for(map<int, int>::iterator it = hash.begin(); it != hash.end(); it ++){
    50             dp[l][0] = 1;
    51             for(int j = 1; j <= l; j ++){
    52                 dp[l][j] = (dp[l-1][j] + (it->second) * dp[l-1][j-1]%mod)%mod;
    53             }
    54             l ++;
    55         }
    56         memset(C, 0, sizeof(C));
    57         C[0] = 1;
    58         for(int i = 0; i < nu; i ++){
    59             C[i + 1] = (C[i] * (nu - i)%mod)*inv(i+1)%mod;
    60         }
    61         LL ans = 0;
    62         for(int x = 0; x <= k && x <= hash.size(); x ++){
    63             ans = (ans + dp[nl][x] * C[k-x]%mod)%mod;
    64         }
    65         printf("%I64d
    ", ans);
    66     }
    67     return 0;
    68 }
    View Code

     

     

  • 相关阅读:
    [转载红鱼儿]delphi 实现微信开发(1)
    Devexpress VCL Build v2013 vol 14.1.3 发布
    [翻译]LSP程序的分类
    睡眠不好
    LuaStudio 9.27 去10分钟退出暗桩板
    vs2012 提示 未能正确加载 "Visual C++ Language Manager Package" 包 的解决办法
    岁月蹉跎
    重新安装系统之前备份
    运动会
    乱思
  • 原文地址:https://www.cnblogs.com/bootstar/p/3222466.html
Copyright © 2011-2022 走看看