• P5686 和积和


    写在前面

    数学题接触的少,卡了半下午,愣是没想到直接往前缀和上考虑,按元素强推莽了半下午

    Description

    直接跳转到题目去啊

    Solution

    \(A,B\) 的前缀和序列分别为 \(sA,sB\)

    那么随便找一组数据,就会发现答案可以由一坨下标相等的前缀和积和减去另外一坨下标不等的前缀和积和。

    而且下标相等的部分正好是对于每个下标 \(i\)\(sA_i sB_i\) 都被计算了 \(n\) 次。

    那么加的部分就很好处理了。即:

    \[n \bullet \sum_{i=1}^{n}sA_i sB_i \]

    减的部分不难看出是 \(sA\)\(sB\) 所有的一一对应且下标不同的组合。

    所以对于每个 \(sA_i\),只需要让它去乘以所有的下标 \(j<i\)\(sB_j\),并将结果求和。

    对于每个 \(sb_i\) 亦然。

    提公因式之后,由于计算过程是静态的,这个过程显然可以通过再预处理出一个超级前缀和 \(SA,Sb\),即前缀和的前缀和来优化实现。

    那么这部分的计算式即为:

    \[\sum_{i=2}^{n}sA_i SB_{i-1} + sB_i SA_{i-1} \]

    总的式子即为:

    \[n \cdot \sum_{i=1}^{n}sA_i sB_i - \sum_{i=2}^{n}sA_i SB_{i-1} + sB_i SA_{i-1} \]

    根据计算式易知时间复杂度为 \(\Theta(n)\)

    code:

    #include<bits/stdc++.h>
    
    #define LL long long
    
    using namespace std;
    const int Maxn = 5e5 + 5;
    const int mod = 1e9 + 7;
    
    inline LL read() {
      LL f = 1, w = 0; char ch = getchar();
      for (; !isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
      for (; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0');
      return f * w;
    }
    
    LL n, t;
    LL a[Maxn], b[Maxn];
    LL Sa[Maxn], Sb[Maxn];
    LL sa[Maxn], sb[Maxn];
    LL ans;
    
    int main()
    {
    	n = read();
    	t = (n % mod + 1 % mod) % mod;
    	for(register int i = 1; i <= n; ++i) a[i] = read() % mod;
    	for(register int i = 1; i <= n; ++i) b[i] = read() % mod;
    	for(register int i = 1; i <= n; ++i)
    	{
    		sa[i] = ((sa[i - 1] % mod) + (a[i] % mod)) % mod;
    		sb[i] = ((sb[i - 1] % mod) + (b[i] % mod)) % mod;
    		Sa[i] = ((Sa[i - 1] % mod) + (sa[i] % mod)) % mod;
    		Sb[i] = ((Sb[i - 1] % mod) + (sb[i] % mod)) % mod;
    		ans = ((ans % mod) + (((((sa[i] % mod) * (sb[i] % mod)) % mod) * (n % mod)) % mod)) % mod;
    	}
    	for(register int i = 2; i <= n; ++i)
    	{
    		ans = ((ans % mod) - (((sa[i] % mod) * (Sb[i - 1] % mod)) % mod) + mod) % mod;
    		ans = ((ans % mod) - (((sb[i] % mod) * (Sa[i - 1] % mod)) % mod) + mod) % mod;
    	}
    	printf("%lld", ans);
    	return 0;
    }
    
  • 相关阅读:
    php.ini 干了些啥?
    为什么你的 phpinfo() 无法显示
    转:反向代理服务器的工作原理
    nginx fastcgi php-fpm的关系梳理
    DOM中offsetLeft与style.left的区别
    移动端与PC端的触屏事件
    移动端适配属性
    移动设备横竖屏监听事件
    关于滚动条滚动不流畅问题
    Oracal
  • 原文地址:https://www.cnblogs.com/zimujun/p/13622543.html
Copyright © 2020-2023  润新知