Master of GCD 【线段树区间更新 || 差分】

 Master of GCD

时间限制: 1 Sec  内存限制: 128 MB
提交: 670  解决: 112
[提交] [状态] [命题人:admin]

题目描述

Hakase has n numbers in a line. At fi rst, they are all equal to 1. Besides, Hakase is interested in primes. She will choose a continuous subsequence [l, r] and a prime parameter x each time and for every l≤i≤r, she will change ai into ai*x. To simplify the problem, x will be 2 or 3. After m operations, Hakase wants to know what is the greatest common divisor of all the numbers.

输入

The first line contains an integer T (1≤T≤10) representing the number of test cases.
For each test case, the fi rst line contains two integers n (1≤n≤100000) and m (1≤m≤100000),where n refers to the length of the whole sequence and m means there are m operations.
The following m lines, each line contains three integers li (1≤li≤n), ri (1≤ri≤n), xi (xi∈{2,3} ),which are referred above.

输出

For each test case, print an integer in one line, representing the greatest common divisor of the sequence. Due to the answer might be very large, print the answer modulo 998244353.

样例输入

复制样例数据

2
5 3
1 3 2
3 5 2
1 5 3
6 3
1 2 2
5 6 2
1 6 2

样例输出

6
2

提示

For the first test case, after all operations, the numbers will be [6,6,12,6,6]. So the greatest common divisor is 6.

只需要求出【1,n】中乘2 和 乘3的最少次数

比赛的时候写的线段树    结束了学弟说用差分可以很快解决,给跪了orz

线段树代码:

#include<iostream>
#include<cstdio>     //EOF,NULL
#include<cstring>    //memset
#include<cstdlib>    //rand,srand,system,itoa(int),atoi(char[]),atof(),malloc
#include<cmath>           //ceil,floor,exp,log(e),log10(10),hypot(sqrt(x^2+y^2)),cbrt(sqrt(x^2+y^2+z^2))
#include<algorithm>  //fill,reverse,next_permutation,__gcd,
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<utility>
#include<iterator>
#include<iomanip>             //setw(set_min_width),setfill(char),setprecision(n),fixed,
#include<functional>
#include<map>
#include<set>
#include<limits.h>     //INT_MAX
#include<bitset> // bitset<?> n
using namespace std;
 
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define fori(x) for(int i=0;i<x;i++)
#define forj(x) for(int j=0;j<x;j++)
#define memset(x,y) memset(x,y,sizeof(x))
#define memcpy(x,y) memcpy(x,y,sizeof(y))
#define all(x) x.begin(),x.end()
#define readc(x) scanf("%c",&x)
#define read(x) scanf("%d",&x)
#define read2(x,y) scanf("%d%d",&x,&y)
#define read3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define print(x) printf("%d\n",x)
#define lowbit(x) x&-x
#define lson(x) x<<1
#define rson(x) x<<1|1
#define pb push_back
#define mp make_pair
typedef pair<int,int> P;
typedef long long LL;
typedef long long ll;
const double eps=1e-8;
const double PI = acos(1.0);
const int INF = 0x3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int MOD = 1e9+7;
const ll mod = 998244353;
const int MAXN = 1e6+7;
const int maxm = 1;
const int maxn = 100000+10;
int T;
int n,m;
struct node {
  ll l, r;
  int lazy2,lazy3;
  ll t;
  ll cnt2,cnt3;
}tree[maxn << 2];
int a,b,x;
 
void pushup(int k){
  tree[k].cnt2 = min(tree[k<<1].cnt2,tree[k<<1|1].cnt2);
  tree[k].cnt3 = min(tree[k<<1].cnt3,tree[k<<1|1].cnt3);
}
void pushdown(int k)
{
    if(tree[k].lazy2)
    {
        tree[k<<1].cnt2 += tree[k].lazy2;
        tree[k<<1|1].cnt2 += tree[k].lazy2;
        tree[k<<1].lazy2 += tree[k].lazy2;
        tree[k<<1|1].lazy2 += tree[k].lazy2;
        tree[k].lazy2 = 0;
    }
    if(tree[k].lazy3)
    {
        tree[k<<1].cnt3 += tree[k].lazy3;
        tree[k<<1|1].cnt3 += tree[k].lazy3;;
        tree[k<<1].lazy3 += tree[k].lazy3;
        tree[k<<1|1].lazy3 += tree[k].lazy3;
        tree[k].lazy3 = 0;
    }
}
 
void build(int l,int r,int k){
  tree[k].l = l;
  tree[k].r = r;
  tree[k].lazy2 = 0;
  tree[k].lazy3 = 0;
  tree[k].cnt2 = 0;
  tree[k].cnt3 = 0;
  if(l == r){
//    tree[k].t = 1 ;
    return ;
  }
  int mid =  (r + l) >> 1 ;
  build(l, mid, k << 1);
  build(mid + 1,r , k << 1|1);
  pushup(k);
}
 
void updata(int a,int b,int k,int x){
  if(tree[k].l == tree[k].r)
  {
    if(x == 2)
      tree[k].cnt2 ++;
    if(x == 3)
      tree[k].cnt3 ++;
     return ;
  }
  if(a <= tree[k].l && b >= tree[k].r )
  {
    if(x == 2){
      tree[k].cnt2 ++;
      tree[k].lazy2 ++;
    }
    if(x == 3){
      tree[k].cnt3 ++;
      tree[k].lazy3 ++;
    }
    return ;
  }
  pushdown(k);
  int mid = (tree[k].l + tree[k].r) >> 1;
  if(a <= mid){
    updata(a,b,k<<1,x);
  }
  if(b > mid){
    updata(a,b,k<<1|1,x);
  }
  pushup(k);
}
 
int main(){
  read(T);
  while(T--){
    read2(n,m);
    build(1,n,1);
    while(m--){
      read3(a,b,x);
      updata(a,b,1,x);
    }
    ll ans = 1;
    for(int i = 0 ; i < tree[1].cnt2 ;i ++){
      ans = ans * 2 % mod;
    }
    for(int i = 0 ; i < tree[1].cnt3 ;i ++){
      ans = ans * 3 % mod;
    }
    printf("%lld\n",ans % mod);
  }
}

差分代码

#include<iostream>
#include<cstdio>     //EOF,NULL
#include<cstring>    //memset
#include<cstdlib>    //rand,srand,system,itoa(int),atoi(char[]),atof(),malloc
#include<cmath>           //ceil,floor,exp,log(e),log10(10),hypot(sqrt(x^2+y^2)),cbrt(sqrt(x^2+y^2+z^2))
#include<algorithm>  //fill,reverse,next_permutation,__gcd,
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<utility>
#include<iterator>
#include<iomanip>             //setw(set_min_width),setfill(char),setprecision(n),fixed,
#include<functional>
#include<map>
#include<set>
#include<limits.h>     //INT_MAX
#include<bitset> // bitset<?> n
using namespace std;

#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define fori(x) for(int i=0;i<x;i++)
#define forj(x) for(int j=0;j<x;j++)
#define memset(x,y) memset(x,y,sizeof(x))
#define memcpy(x,y) memcpy(x,y,sizeof(y))
#define all(x) x.begin(),x.end()
#define readc(x) scanf("%c",&x)
#define read(x) scanf("%d",&x)
#define read2(x,y) scanf("%d%d",&x,&y)
#define read3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define print(x) printf("%d\n",x)
#define lowbit(x) x&-x
#define lson(x) x<<1
#define rson(x) x<<1|1
#define pb push_back
#define mp make_pair
typedef pair<int,int> P;
typedef long long LL;
typedef long long ll;
const double eps=1e-8;
const double PI = acos(1.0);
const int INF = 0x3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int MOD = 1e9+7;
const ll mod = 998244353;
const int MAXN = 1e6+7;
const int maxm = 1;
const int maxn = 100000+10;
int T;
int n,m;
int a,b,x;
int cnt2[maxn],cnt3[maxn];
int tot2[maxn],tot3[maxn];
int main(){
  read(T);
  while(T--){
    memset(cnt2,0);
    memset(cnt3,0);
    memset(tot2,0);
    memset(tot3,0);
    read2(n,m) ;
    while(m--){
      read3(a,b,x);
      if(x == 2) {
        cnt2[a]++,cnt2[b+1]--;
      }
      else {
        cnt3[a]++,cnt3[b+1]--;
      }
    }
    int min2,min3;
    min2 = min3 = inf;
    for(int i = 1; i<= n ;i ++){
        tot2[i] = tot2[i-1] + cnt2[i];
        tot3[i] = tot3[i-1] + cnt3[i];
        min2 = min(min2,tot2[i]);
        min3 = min(min3,tot3[i]);
    }
    ll  ans = 1;
    for(int i = 0 ; i < min2 ;i ++){
      ans = ans * 2 % mod;
    }
    for(int i = 0 ; i < min3 ;i ++){
      ans = ans * 3 % mod;
    }
    cout << ans <<endl;
  }
}

猜你喜欢

转载自blog.csdn.net/kl782636177/article/details/89047145