HDU 6273 Master of GCD

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Qin7_Victory/article/details/80030832

题意:

    给出T组数据(1 <= T  <= 10),每组数据中,有两个数n(1  <= n <= 10^5)和 m (1 <= m <= 10^5)。其中 n 表示有n个由1组成的数, m表示下面给出m组数据,每组数据由 p   q  k 组成。表示区间p 到 q,增大k倍。(k 等于2 或者 3).输出这n个数最终的最大公约数。由于数据比较大,因此需要mod 998244353。 

测试数据 

/*
2
5 3
1 3 2
3 5 2
1 5 3
6 3
1 2 2
5 6 2
1 6 2
*/

思路:

    这道题其实可以根据区间端点来查找。通过分别统计每个1~n个位置中,2的个数以及3的个数。

if(k == 2)
	{
		a[p]++;
		a[q+1]--;	//方便统计有2的个数 
	}
else
	{
		b[p]++;
		b[q+1]--;
        }

(考虑到区间问题,所以这里需要注意两种情况  2~5, 和  6 ~ 7)这两种情况,一种数正好在区间内,另一种,正好再区间外,为了把1~n全部的联系在一起,所以在统计2和3 的个数的时候,只是将第一个端点个统计的,最后一个端点的下一个数先提前减1,这样在相加的时候就不会出现多加的情况。

for(int i = 2; i <= n; i++)
		{
			a[i] += a[i-1];
			b[i] += b[i-1];
			minn1 = min(minn1,a[i]);
			minn2 = min(minn2,b[i]);
                 }

最后通过找出2出现的最少次数和3出现的最小次数,求出它们的乘积,就是1~n之间最大公约数。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;

int m,n;
#define mood 998244353
#define N 100010

int a[N],b[N];

long long int POW(int x,int s)
{
    long long sum = 1;
    while(s)
	{
	    sum = sum*x%mood;
	    s--;
	}
    return sum;
}

int main()
{
    int t;
    int p,q,k;
    scanf("%d",&t);
    while(t--)
    {
	scanf("%d%d",&n,&m);
        memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
        for(int i = 0;i < m; i++)
	{
	    scanf("%d%d%d",&p,&q,&k);
	    if(k == 2)
	    {
		a[p]++;
		a[q+1]--;		//方便统计有2的个数 
	    }
	    else
	    {
		b[p]++;
		b[q+1]--;
	    }
	}
	int minn1 = a[1];
	int minn2 = b[1];
	for(int i = 2; i <= n; i++)
	{
	    a[i] += a[i-1];
	    b[i] += b[i-1];
	    minn1 = min(minn1,a[i]);
	    minn2 = min(minn2,b[i]);
	}
	long long int sum = 0;
	sum = POW(2,minn1);
	sum = sum*POW(3,minn2)%mood;
	printf("%lld\n",sum);	
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/Qin7_Victory/article/details/80030832
今日推荐