BZOJ4921「Lydsy1706月赛」互质序列
吐槽一下BZOJ没有C++11 题还是不难的
题意
在长度为$ 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; }