题目连接:http://www.spoj.com/problems/LGLOVE/

题意:给出n个初始序列a[1],a[2],...,a[n],b[i]表示LCM(1,2,3,...,a[i]),即1~a[i]的最小公倍数
  然后给出三种操作,注意:0<=i,j<n
  0 i j p :a[i]~a[j]都加上p
  1 i j :求LCM(b[i],b[i+1],...,b[j])
  2 i j :求GCD(b[i],b[i+1],...,b[j])

思路:
  求LCM(b[i],b[i+1],...,b[j]),也就是求LCM(1,2,...a[i]),LCM(1,2,...a[i+1]),...,LCM(1,2,...a[j]),这些数的最小公倍数
  如果细心的话可以发现,对于LCM(1,2,...,n1),LCM(1,2,...,n2)
  假设n1<n2,那么LCM(1,2,...,n2)必定是LCM(1,2,...,n1)的倍数;反过来,LCM(1,2,...,n1)必定是LCM(1,2,...,n2)的约数。
  因此针对操作1,其实就是求max(a[i],...,a[j]),设为maxval,然后求出LCM(1,2,...,maxval)即可。
  针对操作2,其实就是求min(a[i],...,a[j]),设为minval,然后求出LCM(1,2,...,minval)即可。

  到此,线段树方面的已经解决了,也就是只要存储该区间的最大值和最小值就行了。
  接下来的话,就是如何预处理出LCM(1,2,...,n)了。
  设z[n]=LCM(1,2,...,n),那么我们可以用下面方式来预处理出所有值:
  z[n]=LCM(z[n-1],n)

  LCM(z[n-1],n)=(z[n-1]*n)/GCD(z[n-1],n)
  而如果就按照这个公式这么做的话,由于最后是求模,首先要将除法的求模改成乘逆,即若a=b/c,那么a%mod=b*c^(m-2)%mod,
  然后用到快速幂,再用辗转相除法。。。不用说,也知道,肯定会TLE!!!

  

  再深入想想,n可以化为p1^a1 * p2^a2 * ... pk^ak,p1,p2,...,pk为n的质因数
  从n的质因式分解中取出一个pi,剩下的设为m,注意m<n,那么n=m*pi
  因为z[n-1]=LCM(1,2,...,n-1),而m<=n-1,所以z[n-1]必定是m的倍数,设z[n-1]=a*m这样的话
  即转化为 LCM(z[n-1],n)=LCM(z[n-1],m*pi)=z[n-1]*m*pi/GCD(z[n-1],m*pi)
  而GCD(z[n-1],m*pi)=m*GCD(a,pi)
  所以LCM(z[n-1],n)=z[n-1]*pi/GCD(a,pi)
  1.若pi与a互质,即pi是这么一个数:在1~n-1中不存在pi这么个质因数,或者存在了,但是个数不够,还要乘一次
    z[n]=z[n-1]*pi
  2.若pi与a不互质,即z[n-1]中pi的个数与n中的个数相同,也就是说n中所有的因子都在z[n-1]中了,那么
    z[n]=z[n-1]

  对于每个质因数,设为p,那么p出现第一次,p^2出现第二次,p^3出现第三次...
  那么我们只要在它第i次出现的时候,结果乘上它就行。
  具体操作是和素数筛选法同时进行的,还是见代码吧。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#define lson rt<<1,L,mid
#define rson rt<<1|1,mid+1,R using namespace std;
const int INF=0x3f3f3f3f;
const int mod=;
const int maxn=;
long long z[maxn*]; //z[i]=LCM(1,2,...,i)
int n,m;
int maxval,minval;
/*
预处理z[i]
z[i]=LCM(1,2,3,...,i) 1<=i<=300000
*/
void init(){
memset(z,,sizeof(z));
z[]=; //0的话,最小公倍数为0
z[]=;
for(int i=;i<maxn*;i++){
if(z[i]==){
for(int j=*i;j<maxn*;j+=i)
z[j]=;
for(int j=i;j<maxn*;j*=i)
z[j]=i; //在i^m 的位置都先设为i,到时只要乘上就行
}
z[i]*=z[i-];
z[i]%mod;
}
} struct Node{
int maxv,minv; //存储区间的最大值,最小值
int add;
int lazy;
}tree[maxn<<]; void pushUp(int rt){
tree[rt].maxv=max(tree[rt<<].maxv,tree[rt<<|].maxv);
tree[rt].minv=min(tree[rt<<].minv,tree[rt<<|].minv);
}
void pushDown(int rt){
if(tree[rt].lazy){
tree[rt<<].add+=tree[rt].add;
tree[rt<<|].add+=tree[rt].add;
tree[rt<<].maxv+=tree[rt].add;
tree[rt<<].minv+=tree[rt].add; //一开始漏写了。。。
tree[rt<<|].maxv+=tree[rt].add; //一开始漏写了。。。
tree[rt<<|].minv+=tree[rt].add;
tree[rt<<].lazy=tree[rt<<|].lazy=true;
tree[rt].lazy=false;
tree[rt].add=;
}
}
void build(int rt,int L,int R){
tree[rt].lazy=false;
tree[rt].add=;
if(L==R){
int v;
scanf("%d",&v);
tree[rt].maxv=tree[rt].minv=v;
return;
}
int mid=(L+R)>>;
build(lson);
build(rson);
pushUp(rt);
} void update(int rt,int L,int R,int l,int r,int c){
if(l<=L&&R<=r){
tree[rt].maxv+=c;
tree[rt].minv+=c;
tree[rt].add+=c;
tree[rt].lazy=true;
return;
}
int mid=(L+R)>>;
pushDown(rt);
if(l<=mid)
update(lson,l,r,c);
if(r>mid)
update(rson,l,r,c);
pushUp(rt);
} void query(int rt,int L,int R,int l,int r,int op){
if(l<=L&&R<=r){
if(op==){
maxval=max(maxval,tree[rt].maxv);
}
else{
minval=min(minval,tree[rt].minv);
}
return;
}
pushDown(rt);
int mid=(L+R)>>;
if(l<=mid)
query(lson,l,r,op);
if(r>mid)
query(rson,l,r,op);
return;
}
int main()
{
init();
int op,a,b,p;
scanf("%d%d",&n,&m);
build(,,n);
for(int i=;i<=m;i++){
scanf("%d",&op);
if(op==){
scanf("%d%d%d",&a,&b,&p);
a++;
b++;
update(,,n,a,b,p);
}
else if(op==){
maxval=-INF;
scanf("%d%d",&a,&b);
a++;b++;
query(,,n,a,b,op);
if(maxval==)
printf("0\n");
else
printf("%lld\n",z[maxval]);
}
else{
minval=INF;
scanf("%d%d",&a,&b);
a++;b++;
query(,,n,a,b,op);
if(minval==)
printf("0\n");
else
printf("%lld\n",z[minval]);
}
}
return ;
}

SPOJ LGLOVE 7488 LCM GCD Love (区间更新,预处理出LCM(1,2,...,n))的更多相关文章

  1. HDU 4348.To the moon SPOJ - TTM To the moon -可持久化线段树(带修改在线区间更新(增减)、区间求和、查询历史版本、回退到历史版本、延时标记不下放(空间优化))

    To the moon Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  2. Can you answer these queries I SPOJ - GSS1 (线段树维护区间连续最大值/最大连续子段和)

    You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ). A query is defi ...

  3. HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是 ...

  4. HDU 1556 Color the ball(线段树区间更新)

    Color the ball 我真的该认真的复习一下以前没懂的知识了,今天看了一下线段树,以前只会用模板,现在看懂了之后,发现还有这么多巧妙的地方,好厉害啊 所以就应该尽量搞懂 弄明白每个知识点 [题 ...

  5. hihoCoder 1080 : 更为复杂的买卖房屋姿势 线段树区间更新

    #1080 : 更为复杂的买卖房屋姿势 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho都是游戏迷,“模拟都市”是他们非常喜欢的一个游戏,在这个游戏里面他们 ...

  6. hdu 3397 Sequence operation(线段树:区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3397 题意:给你一个长度为n的0,1序列,支持下列五种操作, 操作0(0 a b):将a到b这个区间的 ...

  7. 【HDU 4614】Vases and Flowers(线段树区间更新懒惰标记)

    题目0到n-1的花瓶,操作1在下标a开始插b朵花,输出始末下标.操作2清空[a,b]的花瓶,求清除的花的数量.线段树懒惰标记来更新区间.操作1,先查询0到a-1有num个空瓶子,然后用线段树的性质,或 ...

  8. HDU 1698 Just a Hook(线段树/区间更新)

    题目链接: 传送门 Minimum Inversion Number Time Limit: 1000MS     Memory Limit: 32768 K Description In the g ...

  9. HDU 5023 A Corrupt Mayor's Performance Art(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5023 解题报告:一面墙长度为n,有N个单元,每个单元编号从1到n,墙的初始的颜色是2,一共有30种颜色 ...

随机推荐

  1. 在hibernate中使用c3p0数据源

    1.  jar包  hibernate-release-4.1.8.Final\lib\optional\c3p0 2.  加入配置:   <!-- 数据库连接池最大连接数 -->  &l ...

  2. .NET清除Session 的几个方法[clear/removeAll/remove/Abandon]

    1.clear() 清空所有session对象的值,但保留会话   2.removeAll() 调用clear()方法   3.remove("SessionName") 删除某个 ...

  3. python——异常处理

    python处理异常的格式一般如下: try: A部分 Except  .... [as ..]: B部分 [ finally: C部分 Else: D部分 ] ps: 1.不管有没有异常,final ...

  4. [Jsp]防止页面表单重复提交的解决方法

    个人学习笔记,写下方便以后复用. 当我们写了个注册页面时候,用户完成注册并提交,用户注册的资料并录入数据库保存,最不希望出现的是在一个会话中出现多次提交的结果,我们可以通过为请求设置标记来避免此类事件 ...

  5. ROS ZYNQ移植

    1  准备工作 全部是按照官方操作的:http://wiki.ros.org/groovy/Installation/Source   apt-get install python-rosdep py ...

  6. git 合并本地代码到分支

    本地代码合并到dev分支 在local分支提交git add .git commit -m "playbuy" 切换到dev分支git checkout devgit pull合并 ...

  7. Repeat Header / Keep Header Visible in Tables in RS 2008

    You selected "Repeat header rows on each page" or "Keep header rows visible while scr ...

  8. Django Form的学习

    django.forms 是Django处理form的库      本质上可以直接通过对HttpRequest达到同样的效果,但是django.from带来更便捷的处理方式.功能有几点 通过form类 ...

  9. HDU 1465 第六周L题

    Description 大家常常感慨,要做好一件事情真的不容易,确实,失败比成功容易多了!  做好“一件”事情尚且不易,若想永远成功而总从不失败,那更是难上加难了,就像花钱总是比挣钱容易的道理一样.  ...

  10. SQL的自增列如何重置

    第一种方法:首先去除该列自增的标识,然后再修改id的值,成功修改后,再加上自增标识:如果不修改自增标识,会报错:“无法更新标识列”. 第二种方法:删除该自增列,而后重建一个自增列.