题意:
思路: 一开始就在想应该跟前缀和或者后缀和有关,因为这道题很直接能想到的就是O(n^2)的遍历每个link点,但是1e5的数据量是会TLE的,但是在前缀和联系怎么两个邻接点的距离卡了一下。其实知道第i-1个link点到其前面的所有link点的能量之和w(i-1),第i个link点到其前面所有link的能量之和则为w(i)=w(i-1)+num(前面的link点数)*(dis(i-1,i)[ i-1 到 i 的距离]),因为把乘法拆开来其实就是之前的每个dis都加上dis(i-1,i)则这个为第i个link点的前缀能量和,最后再O(n)扫一遍所有的前缀能量和即是答案。
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn=1e5+6;
const ll mod=1e9+7;
char s[maxn];
vector<ll>v;
int main()
{
int i,j;
int n;
scanf("%d",&n);
scanf("%s",s);
int pos=0;
int num=0;
ll ans=0;
v.push_back(0);//处理第一个‘1’;
for(i=0;i<n;i++)
{
if(s[i]=='1')
{
v.push_back((v[v.size()-1]+num*(i-pos))%mod);
num++;
pos=i;
}
}
for(i=0;i<v.size();i++)
{
ans=(ans+v[i])%mod;
}
printf("%lld\n",ans);
return 0;
}