和积和

和积和

这道题侧重于考察数学功底

首先,前缀和优化一般都是能想到的,但是这样的复杂度是 O(n2)

考虑对于小的情况进行模拟。

sai 表示 i=1naisbi 同理。

S(1,1)=sa1sb1

S(1,2)=sa2sb2

S(1,3)=sa3sb3

S(2,2)=(sa2sa1)(sb2sb1)=sa2sb2sa2sb1sa1sb2+sa1sb1

S(2,3)=(sa3sa1)(sb3sb1)=sa3sb3sa3sb1sa1sb3+sa1sb1

S(3,3)=(sa3sa2)(sb3sb2)=sa3sb3sa2sb3sa3sb2+sa2sb2

作和,将右边 +3i=13saisbi,再减掉。

将符号为正的部分和符号为负的部分分别计算

正的:+4i=13saisbi(其实加一项对于左边只是修改了一下系数)。

负的:通过因式分解得 (sa1+sa2+sa3)(sb1+sb2+sb3)(重点是补全 saisbi 这样的项方便因式分解)。

显然,对于每个 n 都有:

要求的 = (n+1)i=1nsaisbii=1nsaii=1nsbi

显然,前缀和 O(1) 查询和 O(n) 枚举。

#include<cstdio>
using namespace std;
#define de(N,x) const int N=x
#define Ls(i,l,r) for(int i=l;i<r;++i)
#define Rs(i,l,r) for(int i=r;i>l;--i)
#define L(i,l) for(int i=1;i<=l;++i)
de(N,500010);
de(mod,1e9+7);
typedef long long ll;
ll a[N],b[N],suma,sumb,ans;
int n;
int main(){
    // freopen("1.in","r",stdin);
    // freopen("1.out","w",stdout);
    // ios::sync_with_stdio(0);
    // cin.tie(0);
    // cout.tie(0);
    scanf("%d",&n);
    L(i, n)scanf("%lld",a+i),(a[i]+=a[i-1])%=mod;
    L(i, n)scanf("%lld",b+i),(b[i]+=b[i-1])%=mod;
    L(i, n){
        (ans+=a[i]*b[i]%mod)%=mod;
        (suma+=a[i])%=mod;
        (sumb+=b[i])%=mod;
    }
    (ans*=n+1)%=mod;
    (ans+=mod-suma*sumb%mod)%=mod;
    printf("%lld",ans);
    return 0;
}

本文作者:wscqwq

本文链接:https://www.cnblogs.com/wscqwq/p/17428031.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   wscqwq  阅读(12)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起