zoukankan      html  css  js  c++  java
  • 【bzoj4921】[Lydsy六月月赛]互质序列 暴力

    题目描述

    给出一个序列,要求删除一段非空区间,使得剩下的数的个数大于等于2。求所有删除方式剩下的数的最大公约数的和。

    输入

     

    第一行包含一个正整数n(3<=n<=100000),表示序列的长度。
    第二行包含n个正整数a_1,a_2,...,a_n(1<=a_i<=10^9),分别表示序列中的每个元素。

    输出

     

    输出一行一个整数,即E*S mod 998244353的值。

    样例输入

    5
    3 4 5 2 9

    样例输出

    14


    题解

    暴力

    显然剩下的一定是左边的一段及右边的一段,可以分别枚举左右的位置。

    根据 【bzoj4052】[Cerc2013]Magical GCD 的结论,一个数不断地与其它数取gcd,最多只会有log个不同的结果,因为gcd减少一次至少要除以2。

    因此可以预处理出从左到右、从右向左的相同gcd段,然后直接枚举左右的段,考虑有多少个区间,直接乱搞即可。

    时间复杂度 $O(nlog n)$

    #include <cstdio>
    #include <cctype>
    #define N 100010
    #define mod 998244353
    typedef long long ll;
    int n , a[N] , lp[35] , lv[35] , lt = 1 , rp[35] , rv[35] , rt = 1;
    inline char nc()
    {
    	static char buf[100000] , *p1 , *p2;
    	return p1 == p2 && (p2 = (p1 = buf) + fread(buf , 1 , 100000 , stdin) , p1 == p2) ? EOF : *p1 ++ ;
    }
    inline int read()
    {
    	int ret = 0; char ch = nc();
    	while(!isdigit(ch)) ch = nc();
    	while(isdigit(ch)) ret = ((ret + (ret << 2)) << 1) + (ch ^ '0') , ch = nc();
    	return ret;
    }
    int gcd(int a , int b)
    {
    	return b ? gcd(b , a % b) : a;
    }
    inline ll calc(int a , int b , int c , int d)
    {
    	if(d - c < 4) return 0;
    	if(b - a >= 2) return 1ll * (a - c) * (d - b);
    	if(a > d - 3) a = d - 3;
    	if(b < c + 3) b = c + 3;
    	return 1ll * (a - c) * (d - b) - 1ll * (a - b + 2) * (a - b + 3) / 2;
    }
    int main()
    {
    	int i , j , t;
    	long long ans = 0;
    	n = read();
    	for(i = 1 ; i <= n ; i ++ ) a[i] = read();
    	lp[1] = 1 , lv[1] = a[1];
    	for(i = 2 ; i <= n ; i ++ )
    	{
    		if((t = gcd(lv[lt] , a[i])) == lv[lt]) lp[lt] ++ ;
    		else lp[++lt] = i , lv[lt] = t;
    		if(i < n) ans = (ans + lv[lt]) % mod;
    	}
    	rp[1] = n , rv[1] = a[n];
    	for(i = n - 1 ; i ; i -- )
    	{
    		if((t = gcd(rv[rt] , a[i])) == rv[rt]) rp[rt] -- ;
    		else rp[++rt] = i , rv[rt] = t;
    		if(i > 1) ans = (ans + rv[rt]) % mod;
    	}
    	rp[0] = n + 1;
    	for(i = 1 ; i <= lt ; i ++ )
    		for(j = 1 ; j <= rt ; j ++ )
    			ans += gcd(lv[i] , rv[j]) * calc(lp[i] , rp[j] , lp[i - 1] , rp[j - 1]);
    	printf("%lld
    " , ans % mod);
    	return 0;
    }
    

     

  • 相关阅读:
    js键盘事件以及键盘事件拦截
    GO-&获取地址与*解引用
    Go-map
    第22课
    第21课
    第20课
    基于spring+quartz的分布式定时任务框架
    DeepLearning (三) 预处理:主成分分析与白化
    白化whitening
    如何使用RestTemplate访问restful服务
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/8073714.html
Copyright © 2011-2022 走看看