zoukankan      html  css  js  c++  java
  • agc031

    T1 题意:给你一个串,求所有子序列个数,满足没有相同字符。1e5,2s。

    解:考虑一个合法的子序列。其中每个字母的出现位置都有(出现次数)种选择。还可以不选,要 + 1。

    然后乘起来就做完了。如果变成子串的话更简单,每个位置为开头的长度不会超过26,直接暴力。本质不同子串就开个hash池判重。

    本质不同子序列......不会。

     1 #include <bits/stdc++.h>
     2 
     3 const int N = 100010, MO = 1e9 + 7;
     4 
     5 char str[N];
     6 int bin[26];
     7 
     8 int main() {
     9     int n;
    10     scanf("%d", &n);
    11     scanf("%s", str);
    12     for(int i = 0; i < n; i++) {
    13         bin[str[i] - 'a']++;
    14     }
    15     int ans = 1;
    16     for(int i = 0; i < 26; i++) {
    17         ans = 1ll * ans * (bin[i] + 1) % MO;
    18     }
    19     printf("%d", (ans + MO - 1) % MO);
    20 
    21     return 0;
    22 }
    AC代码

    T2 题意:给你一个序列,可以若干次选择两个相同的数字,使其之间的数字全部变成这个数字。求最终可能的序列总数。2e5,2s。

    解:发现选出来的序列一定是一些相离的,所以可以DP,设f[i]表示前i位可能的方案总数。那么第i位可能和前面任一个相同的数匹配,f[i] += f[j - 1]。

    同时也可能不匹配,相当于自己跟自己匹配。我们要对所有ai等于一个数的DP值求和,直接开个桶。

    发现有连续相同的数的时候会挂,把它们缩起来。

     1 #include <bits/stdc++.h>
     2 
     3 typedef long long LL;
     4 const int N = 200010, MO = 1e9 + 7;
     5 
     6 int a[N], bin[N], f[N];
     7 
     8 int main() {
     9 
    10     int n;
    11     scanf("%d", &n);
    12     for(int i = 1; i <= n; i++) {
    13         scanf("%d", &a[i]);
    14         if(a[i] == a[i - 1]) {
    15             i--;
    16             n--;
    17         }
    18     }
    19     f[0] = 1;
    20     for(int i = 1; i <= n; i++) {
    21         (bin[a[i]] += f[i - 1]) %= MO;
    22         f[i] = bin[a[i]];
    23     }
    24     printf("%d", f[n]);
    25 
    26     return 0;
    27 }
    AC代码

    T3 题意:求一个1 ~ 2n的排列,满足第一个数是A,最后一个数是B,且相邻两个数的二进制只有一位不同。17,2s。

    解:猜一下结论,如果A和B二进制下不同的位数有偶数个,那么一定无解。其余的有解。

    因为有个头尾的限制,所以我们直接暴力分治。

    每次讨论A和B最高位是否相同。相同的话就先把最高位变一下填2n-1个,然后变回来填后面的。

    不同的话就前2n-1个最高位从A,后面最高位从B。

      1 /**
      2  * There is a start and there is no end in the space. ---Infinity.
      3  * It ruins and goes though there is also a start in stars. ---Finite.
      4  * Only the man who has wisdom can read the most foolish one from the history.
      5  * Fishes living in the sea doesn't know the life in the land.
      6  * It also ruins and goes if they have wisdom.
      7  * It funnier that man exceeds the speed of light than fish start living in the land.
      8  * It can be said that this is an final ultimatum from the god to the people who can fight.
      9  *
     10  * Steins;Gate
     11  */
     12 
     13 #include <bits/stdc++.h>
     14 
     15 const int N = 150000;
     16 
     17 int n, A, B, p[N], top, now, lm, same, dt;
     18 
     19 inline void out(int x) {
     20     for(int i = 0; i < n; i++) {
     21         printf("%d", (x >> i) & 1);
     22     }
     23     return;
     24 }
     25 
     26 inline int cal(int x) {
     27     int ans = 0;
     28     while(x) {
     29         ans++;
     30         x -= x & (-x);
     31     }
     32     return ans;
     33 }
     34 
     35 inline int Abs(int x) {
     36     return x < 0 ? -x : x;
     37 }
     38 
     39 inline int First(int x) {
     40     for(int i = n - 1; i >= 0; i--) {
     41         if((x >> i) & 1) return 1 << i;
     42     }
     43     return 0;
     44 }
     45 
     46 void solve(int n, int l, int r, int a, int b) {
     47     if(n == 1) {
     48         p[l] = a;
     49         p[r] = b;
     50         return;
     51     }
     52     int mid = (l + r) >> 1, nexlm = (1 << (n - 1)) - 1;
     53     if(((a >> (n - 1)) & 1) == ((b >> (n - 1)) & 1)) {
     54         solve(n - 1, mid + 1, r, a & nexlm, b & nexlm);
     55         if((a >> (n - 1)) & 1) {
     56             for(int i = mid + 1; i <= r; i++) {
     57                 p[i] |= 1 << (n - 1);
     58             }
     59             p[l] = p[mid + 1];
     60             solve(n - 1, l + 1, mid + 1, a & nexlm, p[mid + 2] & nexlm);
     61         }
     62         else {
     63             p[l] = p[mid + 1];
     64             solve(n - 1, l + 1, mid + 1, a & nexlm, p[mid + 2] & nexlm);
     65             for(int i = l + 1; i <= mid + 1; i++) {
     66                 p[i] |= (1 << (n - 1));
     67             }
     68         }
     69     }
     70     else {
     71         solve(n - 1, l, mid, a & nexlm, (b & nexlm) ^ 1);
     72         if((a >> (n - 1)) & 1) {
     73             for(int i = l; i <= mid; i++) {
     74                 p[i] |= 1 << (n - 1);
     75             }
     76             solve(n - 1, mid + 1, r, p[mid] & nexlm, b & nexlm);
     77         }
     78         else {
     79             solve(n - 1, mid + 1, r, p[mid] & nexlm, b & nexlm);
     80             for(int i = mid + 1; i <= r; i++) {
     81                 p[i] |= 1 << (n - 1);
     82             }
     83         }
     84     }
     85     return;
     86 }
     87 
     88 int main() {
     89 
     90     scanf("%d%d%d", &n, &A, &B);
     91     lm = (1 << n) - 1, dt = A ^ B, same = dt ^ lm;
     92 
     93     if((cal(dt) & 1) == 0) {
     94         puts("NO");
     95     }
     96     else {
     97         puts("YES");
     98         solve(n, 0, lm, A, B);
     99         for(int i = 0; i <= lm; i++) {
    100             //out(p[i]); printf(" ");
    101             printf("%d ", p[i]);
    102             //puts("");
    103         }
    104     }
    105     return 0;
    106 }
    AC代码

    T4 题意:给定两个排列a和b,定义f(a, b)是一个排列,满足第ai个位置上的数是bi。定义A为一个序列,每个元素是一个排列,且A1 = a, A2 = b, Ai = f(Ai-2, Ai-1),求Ak。10w,1e9,2s。

    解:神仙...

    对于两个排列a和b,定义ab[i] = a[b[i]], a-1[a[i]] = i。于是我们把A的前几项写出来,然后瞎搞一通,就能发现一个奇妙的规律orz...

    直接上官方题解了。

    我们把A的每一个元素拆成sts-1的形式。然后发现si+6 = siba-1b-1a,是个等比数列。然后t是6个一循环的。

    于是我们求出ba-1b-1a的k / 6次方就做完了......注意到求一个排列的k次方只需找出每个元素所在的环,然后跳(k % 环长)步即可。

      1 #include <bits/stdc++.h>
      2 
      3 const int N = 100010;
      4 
      5 int a[N], b[N], c[N], d[N], A[N], n, k, vis[N], B[N], dis[N], C[N], D[N];
      6 int t1[2][N], t2[2][N], t3[2][N], ans[7][N];
      7 std::vector<int> v[N];
      8 
      9 inline int Find(int x, int t) {
     10     int loop = v[vis[x]].size() - 1;
     11     t = (t + dis[x]) % loop;
     12     return v[vis[x]][t];
     13 }
     14 
     15 int main() {
     16 
     17     scanf("%d%d", &n, &k);
     18     k--;
     19     for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
     20     for(int i = 1; i <= n; i++) scanf("%d", &b[i]);
     21 
     22     /// get A  c = b-1  d = a-1
     23     for(int i = 1; i <= n; i++) {
     24         c[b[i]] = i;
     25         d[a[i]] = i;
     26     }
     27     /*for(int i = 1; i <= n; i++) {
     28         printf("%d ", c[i]);
     29     }
     30     puts("");
     31     for(int i = 1; i <= n; i++) {
     32         printf("%d ", d[i]);
     33     }
     34     puts("");*/
     35     for(int i = 1; i <= n; i++) {
     36         A[i] = b[d[c[ a[i] ]]];
     37     }
     38     int t = k / 6;
     39     //printf("t = %d 
    ", t);
     40     /// get B = A^t
     41     for(int i = 1; i <= n; i++) {
     42         if(vis[i]) continue;
     43         /// !vis[i]
     44         int j = i;
     45         v[i].push_back(i);
     46         do {
     47             j = A[j];
     48             dis[j] = v[i].size();
     49             vis[j] = i;
     50             v[i].push_back(j);
     51         } while(j != i);
     52         dis[i] = 0;
     53     }
     54     for(int i = 1; i <= n; i++) {
     55         B[i] = t ? Find(i, t) : i;
     56     }
     57 
     58     /*printf("vis : 
    ");
     59     for(int i = 1; i <= n; i++) {
     60         printf("%d ", vis[i]);
     61     }
     62     puts("");
     63 
     64     printf("A : 
    ");
     65     for(int i = 1; i <= n; i++) {
     66         printf("%d ", A[i]);
     67     }
     68     puts("");*/
     69 
     70     memcpy(t1[0] + 1, B + 1, n * sizeof(int));
     71     memcpy(t1[1] + 1, B + 1, n * sizeof(int));
     72     memcpy(t2[0] + 1, a + 1, n * sizeof(int));
     73     memcpy(t2[1] + 1, b + 1, n * sizeof(int));
     74     for(int i = 1; i <= n; i++) {
     75         t3[0][t1[0][i]] = i;
     76         t3[1][t1[1][i]] = i;
     77     }
     78 
     79     for(int i = 1; i <= n; i++) {
     80         ans[0][i] = t1[0][t2[0][t3[0][i]]];
     81         ans[1][i] = t1[1][t2[1][t3[1][i]]];
     82     }
     83     t = k % 6;
     84     //printf("t = %d 
    ", t);
     85     for(int i = 2; i <= t; i++) {
     86         for(int j = 1; j <= n; j++) {
     87             ans[i][ans[i - 2][j]] = ans[i - 1][j];
     88         }
     89     }
     90 
     91     /*puts("");
     92     for(int i = 0; i <= 1; i++) {
     93         for(int j = 1; j <= n; j++) {
     94             printf("%d ", ans[i][j]);
     95         }
     96         puts("");
     97     }
     98     puts("");*/
     99 
    100     for(int i = 1; i <= n; i++) {
    101         printf("%d ", ans[t][i]);
    102     }
    103 
    104     return 0;
    105 }
    AC代码
  • 相关阅读:
    19年春第六周学习
    Java编程思想
    个人作业4-结对开发地铁
    Hadoop学习笔记—1.基本介绍与环境配置
    ZooKeeper学习第二期--ZooKeeper安装配置
    ZooKeeper学习第一期---Zookeeper简单介绍
    loadrunner--参数化—使用数据文件参数化
    loadrunner--analysis--图表筛选、合并、显示
    loadrunner--并发测试
    session和cookie
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10681333.html
Copyright © 2011-2022 走看看