欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

省赛热身赛9-J--Master of GCD (思维&&区间问题)

程序员文章站 2022-06-07 21:46:28
...

题目链接:http://acm.hnucm.edu.cn/vjudge/contest/view.action?cid=38#problem/J

省赛热身赛9-J--Master of GCD (思维&&区间问题)

【分析】 题意是给定长度的序列,且序列中的初值均为1,给出一系列的对某个区间的操作,使得该区间内的所有数字乘2或3,最后求该序列的最大公因数。

  1. 开两个数组,a、b,分别存储某个位置2的个数和3的个数。计数时,使左端点对应位置的对应数字加1,但右端点的后一个位置对应数字的个数-1,这一点很巧妙。
  2. 通过找出2出现的最少次数和3出现的最小次数,求出它们的乘积,就是1~n之间最大公约数。
  3. 参考:https://blog.csdn.net/Qin7_Victory/article/details/80030832
#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;
}

 

相关标签: 思维 区间问题