zoukankan      html  css  js  c++  java
  • 【 2013 Multi-University Training Contest 6 】

    HDU 4655 Cut Pieces

    假设n个数构成的总数都分成了n段,总数是n*a1*a2*...*an。但是答案显然不会那么多。

    对于相邻的两个ai,ai+1,如果选择相同的颜色,那么就减少了a1*a2*...*ai-1*min(ai,ai+1)*ai+2*ai+3*...*an

    不妨假设n=3,三个数分别是a,b,c。且a<b<c。

    对于所有的排列,只有a,c,b是最优的,结果是3*a*b*c-a*b-b。

    当n>3的时候同样可以得到结论:a1,an,a2,an-1...使得总的段数最多。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<iostream>
     4 typedef long long LL;
     5 #define MOD 1000000007
     6 #define MAXN 1000010
     7 using namespace std;
     8 int arr[MAXN];
     9 int tmp[MAXN];
    10 LL ext_gcd(LL a, LL b, LL &x, LL &y) {
    11     LL t, d;
    12     if (b == 0) {
    13         x = 1;
    14         y = 0;
    15         return a;
    16     }
    17     d = ext_gcd(b, a % b, x, y);
    18     t = x;
    19     x = y;
    20     y = t - a / b * y;
    21     return d;
    22 }
    23 LL invmod(LL a, LL n = MOD) {
    24     LL x, y;
    25     if (ext_gcd(a, n, x, y) != 1)
    26         return -1;
    27     return (x % n + n) % n;
    28 }
    29 int main() {
    30     int T;
    31     int n;
    32     int i;
    33     LL ans;
    34     LL res;
    35     LL mul;
    36     int l, r;
    37     scanf("%d", &T);
    38     while (T--) {
    39         scanf("%d", &n);
    40         ans = n;
    41         mul = 1;
    42         for (i = 0; i < n; i++) {
    43             scanf("%d", &arr[i]);
    44             mul *= arr[i];
    45             mul %= MOD;
    46         }
    47         ans *= mul;
    48         ans %= MOD;
    49         sort(arr, arr + n);
    50         for (l = 0, r = n - 1, i = 1; l <= r; l++, r--) {
    51             if (l == r) {
    52                 tmp[i++] = arr[l];
    53             } else {
    54                 tmp[i++] = arr[l];
    55                 tmp[i++] = arr[r];
    56             }
    57         }
    58         for (i = 2; i <= n; i++) {
    59             res = mul * invmod(tmp[i] * (LL) tmp[i - 1]);
    60             res %= MOD;
    61             res *= min(tmp[i], tmp[i - 1]);
    62             ans -= res % MOD;
    63             ans = (ans % MOD + MOD) % MOD;
    64         }
    65         cout << ans << endl;
    66     }
    67     return 0;
    68 }
    View Code

    HDU 4661 Message Passing

    由于消息传递的次数要求最少,则一个节点将收集所有它的子树的消息之后,再往父节点传递。

    因此,有一个节点将收到所有消息。而发送消息是收集消息的逆过程,总的答案=收集消息的方案数*发送消息的方案数=收集消息的方案数2

    dp[i]表示以i为根的子树,收集到它子孙所有消息的方案数。

    size[i]表示以i为根的子树的节点总数。

    f[i]表示以i为根的树,收集到它子孙所有消息的方案数。

    fac[i]表示i的阶乘。

    dp[i]=fac[size[i]-1]。

    dp[i]/=fac[size[j]],(j是i的儿子)。

    dp[i]*=dp[j],(j是i的儿子)。

      1 #pragma comment(linker,"/STACK:102400000,102400000")
      2 #include<cstdio>
      3 #include<cstring>
      4 typedef long long LL;
      5 #define MAXN 1000010
      6 #define MAXM 2000010
      7 #define MOD 1000000007
      8 int n;
      9 LL fac[MAXN];
     10 LL invfac[MAXN];
     11 int first[MAXN], next[MAXM], v[MAXM], e;
     12 bool vis[MAXN];
     13 LL dp[MAXN];
     14 LL f[MAXN];
     15 int size[MAXN];
     16 LL ext_gcd(LL a, LL b, LL &x, LL &y) {
     17     LL t, d;
     18     if (b == 0) {
     19         x = 1;
     20         y = 0;
     21         return a;
     22     }
     23     d = ext_gcd(b, a % b, x, y);
     24     t = x;
     25     x = y;
     26     y = t - a / b * y;
     27     return d;
     28 }
     29 LL invmod(LL a, LL n = MOD) {
     30     LL x, y;
     31     if (ext_gcd(a, n, x, y) != 1)
     32         return -1;
     33     return (x % n + n) % n;
     34 }
     35 void init() {
     36     int i;
     37     fac[0] = 1;
     38     for (i = 1; i < MAXN; i++) {
     39         fac[i] = fac[i - 1] * i;
     40         fac[i] %= MOD;
     41     }
     42     for (i = 0; i < MAXN; i++) {
     43         invfac[i] = invmod(fac[i]);
     44     }
     45 }
     46 inline void addEdge(int x, int y) {
     47     v[e] = y;
     48     next[e] = first[x];
     49     first[x] = e++;
     50 }
     51 void getSize(int x) {
     52     vis[x] = true;
     53     size[x] = 1;
     54     for (int i = first[x]; i != -1; i = next[i]) {
     55         int y = v[i];
     56         if (!vis[y]) {
     57             getSize(y);
     58             size[x] += size[y];
     59         }
     60     }
     61 }
     62 void dfs(int x) {
     63     vis[x] = true;
     64     dp[x] = fac[size[x] - 1];
     65     for (int i = first[x]; i != -1; i = next[i]) {
     66         int y = v[i];
     67         if (!vis[y]) {
     68             dfs(y);
     69             dp[x] *= invfac[size[y]];
     70             dp[x] %= MOD;
     71             dp[x] *= dp[y];
     72             dp[x] %= MOD;
     73         }
     74     }
     75 }
     76 void search(int x, int pre) {
     77     vis[x] = true;
     78     if (pre != -1) {
     79         f[x] = fac[n - 1];
     80 
     81         f[x] *= invfac[n - size[x]];
     82         f[x] %= MOD;
     83         LL tmp = f[pre];
     84         tmp *= invfac[n - 1];
     85         tmp %= MOD;
     86         tmp *= fac[n - 1 - size[x]];
     87         tmp %= MOD;
     88         tmp *= fac[size[x]];
     89         tmp %= MOD;
     90         tmp *= invmod(dp[x]);
     91         tmp %= MOD;
     92         f[x] *= tmp;
     93         f[x] %= MOD;
     94         for (int i = first[x]; i != -1; i = next[i]) {
     95             int y = v[i];
     96             if (!vis[y]) {
     97                 f[x] *= invfac[size[y]];
     98                 f[x] %= MOD;
     99                 f[x] *= dp[y];
    100                 f[x] %= MOD;
    101             }
    102         }
    103     }
    104     for (int i = first[x]; i != -1; i = next[i]) {
    105         int y = v[i];
    106         if (!vis[y]) {
    107             search(y, x);
    108         }
    109     }
    110 }
    111 int main() {
    112     int T;
    113     int i;
    114     int x, y;
    115     int ans;
    116     init();
    117     scanf("%d", &T);
    118     while (T--) {
    119         scanf("%d", &n);
    120         e = 0;
    121         memset(first, -1, sizeof(first));
    122         for (i = 1; i < n; i++) {
    123             scanf("%d%d", &x, &y);
    124             addEdge(x, y);
    125             addEdge(y, x);
    126         }
    127         memset(vis, false, sizeof(vis));
    128         getSize(1);
    129         memset(vis, false, sizeof(vis));
    130         dfs(1);
    131         memset(vis, false, sizeof(vis));
    132         f[1] = dp[1];
    133         search(1, -1);
    134         ans = 0;
    135         for (i = 1; i <= n; i++) {
    136             ans += (f[i] * f[i]) % MOD;
    137             ans %= MOD;
    138         }
    139         printf("%d
    ", ans);
    140     }
    141     return 0;
    142 }
    View Code

    HDU 4662 MU Puzzle

    从给定的字符串变成MI需要反着操作。

    (1)将U替换成III。

    (2)添加x个UU,即添加x个IIIIII。

    假设有cnt个I,添加x个UU,那么一共有cnt+6x个I,又要满足cnt+6x=2y。判断是否存在这样的x满足方程即可。

     1 #include<cstdio>
     2 #include<cstring>
     3 #define MAXN 1000010
     4 char str[MAXN];
     5 bool isOK(int len) {
     6     if (str[0] != 'M') {
     7         return false;
     8     }
     9     for (int i = 1; i < len; i++) {
    10         if (str[i] == 'M') {
    11             return false;
    12         }
    13     }
    14     return true;
    15 }
    16 int main() {
    17     int T;
    18     int len;
    19     int cnt;
    20     int i;
    21     scanf("%d", &T);
    22     while (T--) {
    23         scanf(" %s", str);
    24         len = strlen(str);
    25         if (isOK(len)) {
    26             cnt = 0;
    27             for (i = 1; i < len; i++) {
    28                 if (str[i] == 'U') {
    29                     cnt += 3;
    30                 } else {
    31                     cnt++;
    32                 }
    33             }
    34             if (len == 2 && str[1] == 'I') {
    35                 puts("Yes");
    36             } else if (cnt % 6 == 2 || cnt % 6 == 4) {
    37                 puts("Yes");
    38             } else {
    39                 puts("No");
    40             }
    41         } else {
    42             puts("No");
    43         }
    44     }
    45     return 0;
    46 }
    View Code

    HDU 4664 Triangulation

    SG打表找规律。

    mex是不属于这个集合的最少非负整数。

    sg(x)是mex{sg(y)|y是x的后继状态}。

    游戏和的SG函数值是它的所有子游戏SG函数值的异或。

    n个游戏的异或和为0,先手必败。

     1 #include<cstdio>
     2 #include<cstring>
     3 #define MAXN 1010
     4 int sg[MAXN];
     5 bool vis[MAXN];
     6 int SG(int n) {
     7     if (n == 0) {
     8         sg[n] = 0;
     9     } else if (n == 1) {
    10         sg[n] = 0;
    11     } else if (n == 2) {
    12         sg[n] = 1;
    13     } else if (n == 3) {
    14         sg[n] = 1;
    15     } else if (sg[n] == -1) {
    16         int i;
    17         memset(vis, false, sizeof(vis));
    18         for (i = 0; i <= n - 2; i++) {
    19             vis[SG(i) ^ SG(n - i - 2)] = true;
    20         }
    21         for (i = 0;; i++) {
    22             if (!vis[i]) {
    23                 break;
    24             }
    25         }
    26         sg[n] = i;
    27     }
    28     return sg[n];
    29 }
    30 void init() {
    31     int i;
    32     memset(sg, -1, sizeof(sg));
    33     for (i = 0; i < MAXN; i++) {
    34         sg[i] = SG(i);
    35     }
    36 }
    37 int getSG(int n) {
    38     if (n < MAXN) {
    39         return sg[n];
    40     } else {
    41         return sg[n % 34 + 2 * 34];
    42     }
    43 }
    44 int main() {
    45     int T;
    46     int n;
    47     int tmp;
    48     int res;
    49     init();
    50     scanf("%d", &T);
    51     while (T--) {
    52         scanf("%d", &n);
    53         res = 0;
    54         while (n--) {
    55             scanf("%d", &tmp);
    56             res ^= getSG(tmp);
    57         }
    58         if (res) {
    59             puts("Carol");
    60         } else {
    61             puts("Dave");
    62         }
    63     }
    64     return 0;
    65 }
    View Code

    HDU 4665 Unshuffle

    若一个数只出现两次,则第一个数属于0,第二个数属于1。

    若一个数出现了四次,则第一个数属于0,第四个数属于1,其他两个都有可能。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<vector>
     4 #define MAXN 2010
     5 using namespace std;
     6 int arr[MAXN];
     7 char str[MAXN];
     8 bool flag;
     9 int idx[MAXN];
    10 int cnt[MAXN];
    11 int st[2][MAXN];
    12 int belong[MAXN];
    13 int n;
    14 vector<int> pos[MAXN];
    15 void dfs(int x, int p1, int p2) {
    16     if (x > n) {
    17         flag = true;
    18     }
    19     if (flag) {
    20         return;
    21     }
    22     if (p1 > 0 && p2 > 0
    23             && arr[st[0][min(p1, p2)]] != arr[st[1][min(p1, p2)]]) {
    24         return;
    25     }
    26     if (belong[x] == 0) {
    27         st[0][p1 + 1] = x;
    28         dfs(x + 1, p1 + 1, p2);
    29     } else if (belong[x] == 1) {
    30         st[1][p2 + 1] = x;
    31         dfs(x + 1, p1, p2 + 1);
    32     } else {
    33         st[0][p1 + 1] = x;
    34         belong[pos[arr[x]][2]] = 1;
    35         dfs(x + 1, p1 + 1, p2);
    36 
    37         if (!flag) {
    38             st[1][p2 + 1] = x;
    39             belong[pos[arr[x]][2]] = 0;
    40             dfs(x + 1, p1, p2 + 1);
    41 
    42             belong[pos[arr[x]][2]] = -1;
    43         }
    44     }
    45 }
    46 int main() {
    47     int T;
    48     int i;
    49     scanf("%d", &T);
    50     while (T--) {
    51         scanf("%d", &n);
    52         memset(idx, 0, sizeof(idx));
    53         memset(cnt, 0, sizeof(cnt));
    54         for (i = 1; i <= n; i++) {
    55             scanf("%d", &arr[i]);
    56             cnt[arr[i]]++;
    57             idx[i] = cnt[arr[i]];
    58             pos[arr[i]].clear();
    59         }
    60         memset(belong, -1, sizeof(belong));
    61         for (i = 1; i <= n; i++) {
    62             if (idx[i] == 1) {
    63                 belong[i] = 0;
    64             } else if (idx[i] == 2 && cnt[arr[i]] == 2) {
    65                 belong[i] = 1;
    66             } else if (idx[i] == 4) {
    67                 belong[i] = 1;
    68             }
    69             pos[arr[i]].push_back(i);
    70         }
    71         flag = false;
    72         dfs(1, 0, 0);
    73         for (i = 1; i <= (n >> 1); i++) {
    74             str[st[0][i]] = '0';
    75             str[st[1][i]] = '1';
    76         }
    77         for (i = 1; i <= n; i++) {
    78             putchar(str[i]);
    79         }
    80         putchar('
    ');
    81     }
    82     return 0;
    83 }
    View Code
  • 相关阅读:
    oracle 数据库服务名怎么查
    vmware vsphere 6.5
    vSphere虚拟化之ESXi的安装及部署
    ArcMap中无法添加ArcGIS Online底图的诊断方法
    ArcGIS中字段计算器(高级计算VBScript、Python)
    Bad habits : Putting NOLOCK everywhere
    Understanding the Impact of NOLOCK and WITH NOLOCK Table Hints in SQL Server
    with(nolock) or (nolock)
    What is “with (nolock)” in SQL Server?
    Changing SQL Server Collation After Installation
  • 原文地址:https://www.cnblogs.com/DrunBee/p/3246403.html
Copyright © 2011-2022 走看看