您的位置:首页 > 其它

20160802 求和 找规律

2016-08-08 19:00 267 查看




设位置为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%=moder
using 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: