题目连接: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. 基于 ArcGIS Silverlight API开发的WebGIS应用程序的部署

    部署流程概述 在微软的iis服务器上部署基于ArcGIS  Silverlight API的应用程序,主要包括以下几个步骤: 1)(可选)部署GIS服务 如果需要将GIS服务也部署在Web服务器上,则 ...

  2. jQuery 手风琴侧边菜单

    动手做了一个简单手风琴菜单,上图: 点击 B 可收缩 C 列表,点击 C 改变自身和父节点 B 的样式,悬浮时均有不同的样式改变. 先看页面代码,列表的嵌套: <div id="men ...

  3. 安装WordPress详细教程指南

    最近准备自己建一个个人博客,以便分享一些自己工作生活中的一些观点及经验,建博客当然选wordpress,毕竟wordpress是为博客而生的嘛.下边记录一下自己安装WordPress的详细过程指南,亦 ...

  4. Centos6.4版本下搭建LAMP环境

    Centos6.4版本下搭建LAMP环境 配置yum mkdir/mnt/cdrom mount/dev/cdrom  /mnt/cdrom 装载光盘 vi /etc/yum.repos.d/Cent ...

  5. 使用tortoise git管理gitolite版本库

    gitolite-admin是用于管理git版本库的版本库,将其从服务器上clone下来. 使用tortoise git clone的时候需要指定私钥,私钥的格式是ppk的,需要使用putty的PUT ...

  6. [react native] Error loading page

    如上图显示的错误,解决方法如下: 在react native ios项目的info.plist文件中,新增一个属性. 在Info.plist中添加NSAppTransportSecurity类型Dic ...

  7. JavaScript 垃圾回收机制分析

    同C# .Java一样可以手工调用垃圾回收程序,但是由于其消耗大量资源,而且手工调用的不会比浏览器判断的准确,所以不推荐手工调用垃圾回收.   最近精力主要用在了Web 开发上,读了一下<Jav ...

  8. 图解 CSS: 理解样式表的逻辑(转载)

    原文:http://www.cnblogs.com/del/archive/2009/02/01/1382141.html 样式表可以是外部的.内联的或嵌入的; 链接外部样式文件一般是:<lin ...

  9. Python脚本控制的WebDriver 常用操作 <十六> 处理对话框

    下面将使用webdriver来处理一些页面跳出的对话框事件 测试用例场景 页面上弹出的对话框是自动化测试经常会遇到的一个问题.前端框架的对话框经常是div形式的,下面是一些常见的对话框操作事件: 打开 ...

  10. selenium-python iframe用法

    易迅的登录方法,因为页面有很多iframe的内置框架,需要先逐级定位到登录元素所在的iframe才行 使用方法switch_to_frame('id-name') from selenium impo ...