20160802 求和 找规律

来源:互联网 发布:oc第三方网络请求 编辑:程序博客网 时间:2024/05/18 03:32

这里写图片描述这里写图片描述

设位置为pos,数字为num,则每一个节点新加入时,与他前面的节点产生的贡献值,等于前面节点个数此pos此num+前面pos和此num+前面num和此pos+前面各num*pos的和。因此每加入一个节点,计算完新产生的贡献,就可以把它和前面的节点合到一起了。时间复杂度O(N)。
因为奇数位置上的点和偶数位置上的点不能合,所以要开两个数组。

自己的代码:

#include<cstdio>#define moder 10007#define gm 100001#define ck(x) if(x>=moder) x%=moderusing namespace std;typedef unsigned long long ull;int n,m;int ni[gm],ci[gm];ull ans;struct card{    ull qtt;    ull posn;    ull numn;    ull cs;    card():qtt(0),posn(0),numn(0),cs(0){}}e[gm][2];inline void merge(int col,int num,int pos){    card &t=pos&1?e[col][0]:e[col][1];    ck(num);ck(pos);    ans+=(((t.qtt*num*pos)%moder)+((t.posn*num)%moder)+((t.numn*pos)%moder)+t.cs)%moder;    ck(ans);    t.qtt++; ck(t.qtt);    t.posn+=pos; ck(t.posn);    t.numn+=num; ck(t.numn);    t.cs+=pos*num; ck(t.cs);}int main(){    freopen("sum.in","r",stdin);    freopen("sum.out","w",stdout);    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++) scanf("%d",&ni[i]);    for(int i=1;i<=n;i++) scanf("%d",&ci[i]);    for(int i=1;i<=n;i++) merge(ci[i],ni[i],i);    printf("%llu",ans);    return 0;}
0 0
原创粉丝点击