BZOJ4921「Lydsy1706月赛」互质序列

吐槽一下BZOJ没有C++11  题还是不难的

BZOJ 4921


题意

在长度为$ n$的数列中去掉非空的连续一段并保证剩下数字不少于$ 2$

求合法的所有方案中剩下数字的最大公约数的总和


$Solution$

记录一下前后缀$ gcd$

容易发现不同的$ gcd$的数量是$ log$级别的

为写起来方便用$ map$存即可


$ my \ code$

#include<bits/stdc++.h>
#define rt register int
#define ll long long
#define p 998244353
using namespace std;
int k,m,n,x,y,z,cnt,ans;
int qz[100010],hz[100010],a[100010];
map<int,int>s1,s2;
int main(){
    scanf("%d",&n);
    for(rt i=1;i<=n;i++)scanf("%d",&a[i]);
    qz[1]=a[1];for(rt i=2;i<=n;i++)qz[i]=__gcd(qz[i-1],a[i]);
    hz[n]=a[n];for(rt i=n-1;i>=1;i--)hz[i]=__gcd(hz[i+1],a[i]);
    ll ans=0;for(rt i=2;i<n;i++)ans+=qz[i]+hz[i];ans%=p;
    for(rt i=1;i<=n-2;i++)s1[qz[i]]++;
    for(rt i=n-2;i>=1;i--){
        s2[hz[i+2]]++;
        for(map<int,int>::iterator it=s2.begin();it!=s2.end();it++)
        (ans+=1ll*__gcd(qz[i],(*it).first)*(*it).second%p)%=p;
    }
    cout<<ans;
    return 0;
}

 

posted @ 2018-12-17 19:26  Kananix  阅读(265)  评论(0编辑  收藏  举报

Contact with me