纠结了很久的题目。看上去是一道裸的线段树,但是需要对数据做特殊的处理。
题意:n(1<=n<=10^5)个数字,q(1<=q<=10^5)个操作。每个操作可能有3种情况:1.询问[k1,k2]区间数字的GCD%p; 2.询问[k1,k2]区间数字的LCM%p; 3.将k位置的数字改为v。对于前两个操作输出对应的值。题目保证这n个数不管在什么时候都不超过100
对点修改,对区间查询,最基础的线段树。但是,前100个自然书的LCM非常大,超long long,不能直接套线段树。要用到位压缩。前100个数字里包含25个质数分别是:2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97。在一个数字里,质因子2最多出现6次(用3位2进制数表示),3最多出现4次(用3位2进制数表示),5最多出现2次(用2位2进制数表示),7最多出现2次,其余的最多出现1次(用1位2进制数表示)。全加起来3+3+2+2+21=31位,也就是说可以用一个32位整数表示质因子的数量。剩下的就是裸线段树了。
有2点需要注意的,写在代码注释里了。
#include<stdio.h>
#include<iostream>
using namespace std;
#define Maxn 100010
struct node
{
int l,r,gcd,lcm;
}tree[Maxn*4];
int n,q,A[Ma