题意:
输入T组数据,每组数据有n个数,m个操作,下面有m行,每行有三个数,前两个为区间,把这个区间中每个数都乘以第三个数(只会是 2,3)求最后这n个数的最大公约数,刚开始这n个数都是1 。
题解:
记录每个数乘上的2和3的数量,结果就是最少数量的2和最少数量的3的乘积。
代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int MAXN = 100005;
const int MOD = 998244353;
struct T{
int num2,num3;
int lazy2,lazy3;
}Tree[MAXN*3];
void Up(int temp){
Tree[temp].num2 = min(Tree[temp<<1].num2,Tree[temp<<1|1].num2);
Tree[temp].num3 = min(Tree[temp<<1].num3,Tree[temp<<1|1].num3);
}
void Build(int temp,int l,int r){
Tree[temp].num2 = Tree[temp].num3 = 0;
Tree[temp].lazy2 = Tree[temp].lazy3 = 0;
if(l == r)return;
int m = l + (r-l)/2;
Build(temp<<1,l,m);
Build(temp<<1|1,m+1,r);
}
void PushDown(int temp){
if(Tree[temp].lazy2){
Tree[temp<<1].lazy2 += Tree[temp].lazy2;
Tree[temp<<1].num2 += Tree[temp].lazy2;
Tree[temp<<1|1].lazy2 += Tree[temp].lazy2;
Tree[temp<<1|1].num2 += Tree[temp].lazy2;
Tree[temp].lazy2 = 0;
}
if(Tree[temp].lazy3){
Tree[temp<<1].lazy3 += Tree[temp].lazy3;
Tree[temp<<1].num3 += Tree[temp].lazy3;
Tree[temp<<1|1].lazy3 += Tree[temp].lazy3;
Tree[temp<<1|1].num3 += Tree[temp].lazy3;
Tree[temp].lazy3 = 0;
}
}
void Updata(int temp,int l,int r,int ql,int qr,int value){
if(ql>r || qr<l)return;
if(ql<=l && qr>=r){
if(value == 2){
Tree[temp].num2++;
Tree[temp].lazy2++;
}
else{
Tree[temp].num3++;
Tree[temp].lazy3++;
}
return ;
}
PushDown(temp);
int m = l + (r-l)/2;
if(ql <= m)Updata(temp<<1,l,m,ql,qr,value);
if(qr > m)Updata(temp<<1|1,m+1,r,ql,qr,value);
Up(temp);
}
int main(){
int T,n,m;
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);
Build(1,1,n);
int a,b,value;
while(m--){
scanf("%d %d %d",&a,&b,&value);
Updata(1,1,n,a,b,value);
}
long long sum = 1;
for(int i=1 ; i<=Tree[1].num2 ; ++i)sum = (sum*2)%MOD;
for(int i=1 ; i<=Tree[1].num3 ; ++i)sum = (sum*3)%MOD;
printf("%lld\n",sum);
}
return 0;
}