[BZOJ 4921][Lydsy1706月赛]互质序列

传送门

因为区间 gcd 的变换不会超过 log 个,所以我们可以暴力枚举区间起点,复杂度是 n*logn

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define rep(i,a,b) for(int i=a;i<=b;++i)
 4 #define fd(i,a,b) for(int i=a;i>=b;--i)
 5 const int maxn=100010,mod=998244353;
 6 template <typename T> bool check_Max(T &x, const T&y) {return x<y?x=y,false:true;}
 7 template <typename T> bool check_Min(T &x, const T&y) {return x>y?x=y,false:true;} 
 8 inline int gi() {
 9     int x=0; char o; bool f=true; for(;!isdigit(o=getchar());) if(o=='-') f=false;
10     for(;isdigit(o);o=getchar()) x=(x<<1)+(x<<3)+(o&15); return f?x:~x+1;
11 }
12 template <typename T> inline void Md(T &x) {if(x>=mod) x-=mod;}
13 int gcd(int x,int y) { return x?gcd(y%x,x):y;}
14 int gd1[maxn],gd2[maxn],nt[maxn],a[maxn],n,ans;
15 int main() {
16 #ifndef ONLINE_JUDGE
17     freopen("10.in","r",stdin);
18 #endif
19     n=gi(); rep(i,1,n) gd1[i]=gd2[i]=a[i]=gi();
20     rep(i,2,n) gd1[i]=gcd(gd1[i-1],gd1[i]); fd(i,n-1,1) gd2[i]=gcd(gd2[i+1],gd2[i]);
21     rep(i,2,n) nt[i]=gd2[i]==gd2[i-1]?nt[i-1]:i-1;
22     rep(i,2,n) {
23         int pos=gd1[i-1]; if(i>2) Md(ans+=pos%mod);
24         int L=n;
25         while(L>i) {
26             int R=max(i+1,nt[L]+1); pos=gcd(pos,gd2[R]);
27 //            printf("i=%d L=%d R=%d pos=%d--\n",i,L,R,pos);//de bug
28             Md(ans+=1LL*pos*(L-R+1)%mod); L=R-1;
29         }
30     }
31     int L=n-1,R,pos=gd2[L];
32     while(L>1) {
33         R=max(2,nt[L]+1),pos=gd2[R]; 
34 //        peintf("L=%d R=%d pos=%d\n",L,R,pos); //de bug
35         Md(ans+=1LL*pos*(L-R+1)%mod); L=R-1;
36     }
37     printf("%d\n",ans);
38     return 0;
39 }


今天的水题计划就到这里了,顺带提一句,今天S8世界总决赛 小组赛IG vs GRX时Stitch 的反向Q,连皮肤都和当年韦神的一样

放个图感受一下

 


 

 

转载于:https://www.cnblogs.com/miecoku/p/9775159.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值