• 杭电多校2020-6-1001 Road To The 3rd Building


    Road To The 3rd Building

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/262144 K (Java/Others)
    链接:http://acm.hdu.edu.cn/showproblem.php?pid=6827

    题意:给定n棵树,每棵树都有自己的“美丽值”,第k棵树的美丽值为sk。已知一条路径是从第i课树走到第j棵树,i<=j,这条路径的美丽值为求所有路径的期望值,答案mod 10^9+7.

    数据范围:T个样例

     

    保证所有样例的n总和不超过10^6

    题解:列表观察每一棵树被计算的次数,可以发现规律:

    N=7

                                      树的编号i

              1 2 3 4 5 6 7   

    分母大小       1       1 1 1 1 1 1 1

                       2    1 2 2 2 2 2 1

               3    1 2 3 3 3 2 1

            4  1 2 3 4 3 2 1

            5  1 2 3 3 3 2 1

            6  1 2 2 2 2 2 1

            7  1 1 1 1 1 1 1

    N=6

                                  树的编号i

            1 2 3 4 5 6

    分母大小     1  1 1 1 1 1 1

             2  1 2 2 2 2 1

                       3  1 2 3 3 2 1

             4  1 2 3 3 2 1

                5  1 2 2 2 2 1

           6  1 1 1 1 1 1

    可以发现,计算次数是呈矩形逐渐缩小的。利用这个规律,suminv组记录逆元前缀和,sum数组记录树的编号前缀和,逐级相乘即可。

    计算的时候没有注意到逆元前缀和能用线性求逆元计算,不过时间也没慢多少。(别骂了,我知道我是菜鸡)

    suminv相减一定要注意负值得问题。一开始觉得最后结果时处理负数就可以了,样例和手造样例也过了,结果wa了几发,过了一会才发现这个问题。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 #define ull unsigned long long
     5 //#define LOCAL
     6 const int N = 2 * 100000 + 5;
     7 const int mod = 1e9 + 7;
     8 ll s[N], sum[N];
     9 ll inv[N], suminv[N];
    10 ll ans;
    11 inline ll qpow(int a, long long b)
    12 {
    13     ll c = 1;
    14     for (; b; b >>= 1)
    15     {
    16         if (b & 1)
    17             c = (ll)c * a % mod;
    18         a = (ll)a * a % mod;
    19     }
    20     return c;
    21 }
    22 inline int read()
    23 {
    24     int x = 0, f = 1;
    25     char ch = getchar();
    26     while (ch < '0' || ch > '9')
    27     {
    28         if (ch == '-')
    29             f = -1;
    30         ch = getchar();
    31     }
    32     while (ch >= '0' && ch <= '9')
    33     {
    34         x = (x << 1) + (x << 3) + (ch ^ 48);
    35         ch = getchar();
    36     }
    37     return x * f;
    38 }
    39 inline void init()
    40 {
    41     for (int i = 1; i <= N; i++)
    42     {
    43         inv[i] = qpow(i, mod - 2);
    44         suminv[i] = suminv[i - 1] + inv[i];
    45         if (suminv[i] >= mod)
    46             suminv[i] -= mod;
    47     }
    48 }
    49 int main()
    50 {
    51 #ifdef LOCAL
    52     freopen("in.txt"" r", stdin);
    53     //   freopen("out.txt", " w", stdout);
    54 #endif
    55     init();
    56     int T = read();
    57     while (T--)
    58     {
    59         int n = read();
    60         for (int i = 1; i <= n; i++)
    61         {
    62 
    63             s[i] = read();
    64             sum[i] = sum[i - 1] + s[i];
    65         }
    66         ans = 0;
    67         int l = (n >> 1);
    68 
    69         for (int i = 1; i <= (n & 1 ? l + 1 : l); i++)
    70         {
    71             ll qaq = suminv[n - i + 1] - suminv[i - 1];
    72             if(qaq<0)
    73                 qaq += mod;
    74             ans += qaq % mod * ((sum[n - i + 1] - sum[i - 1]) % mod) % mod;
    75             ans %= mod;
    76         }
    77 
    78         ans *= 2 * inv[n] % mod * inv[n + 1] % mod;
    79         ans %= mod;
    80         if (ans < 0)
    81             ans += mod;
    82         printf("%lld
    ", ans);
    83     }
    84 }
  • 相关阅读:
    百度高级搜索技巧
    JRebel插件使用详解
    css3自适应布局单位vw,vh详解
    vue的MVVM原理
    JS实现全屏和退出全屏
    设置不定宽高的元素垂直水平居中
    微信小程序启动更新机制
    了解MVVM原理
    xss攻击和csrf攻击的定义及区别
    跨站脚本漏洞(XSS)基础讲解
  • 原文地址:https://www.cnblogs.com/akaku/p/13511017.html
Copyright © 2020-2023  润新知