题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4630

题意:给你n个数据范围在[1,n]中的数,m个操作,每个操作一个询问[L,R],让你求区间[L,R]内任意两个数的最大公倍数。

思路:是线段树是必然的 O.O 。顺着来不好解决,只能离线处理试试。按r从小到大排序,数组a[i]从左到右扫一遍,对每个a[i]都要进行处理,先因数分解,pre[X]表示约数X在前面最后出现的位置。开始处理的是pre[X]到当前位置r都对约数X进行比较更新,后面想想这样是有问题,因为这样不能保证约数X出现在pre[X]与r的中间位置,所以这里我们只对位置pre[X]进行最大约数的比较更新,这样就能很好的解决当询问[pre[X],r]时,这个约数恰好就出现在区间段内,pre[X]更新为r,起初的对询问区间段r排序能保证这样处理的结果是正确的。

恩,不错,是一道好题。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std; #define lz 2*u,l,mid
#define rz 2*u+1,mid+1,r
const int maxn=;
int maxx[*maxn], flag[*maxn];
int a[maxn];
int pre[maxn];
int n, m, T;
vector<int>vt; struct node
{
int l, r, id;
int ans;
friend bool operator<(const node A, const node B)
{
return A.r<B.r;
}
}f[maxn]; bool cmp(node A, node B)
{
return A.id<B.id;
} void push_down(int u, int l, int r)
{
if(flag[u])
{
flag[*u]=max(flag[*u],flag[u]);
flag[*u+]=max(flag[*u+],flag[u]);
maxx[*u]=max(maxx[*u],flag[u]);
maxx[*u+]=max(maxx[*u+],flag[u]);
flag[u]=;
}
} void Update(int u, int l, int r, int tl, int tr, int val)
{
maxx[u]=max(maxx[u],val);
if(tl<=l&&r<=tr)
{
flag[u]=max(flag[u],val);
maxx[u]=max(maxx[u],val);
return ;
}
push_down(u,l,r);
int mid=(l+r)>>;
if(tr<=mid) Update(lz,tl,tr,val);
else if(tl>mid) Update(rz,tl,tr,val);
else
{
Update(lz,tl,mid,val);
Update(rz,mid+,tr,val);
}
} int Query(int u, int l, int r, int tl, int tr)
{
if(tl<=l&&r<=tr) return maxx[u];
push_down(u,l,r);
int mid=(l+r)>>;
if(tr<=mid) return Query(lz,tl,tr);
else if(tl>mid) return Query(rz,tl,tr);
else
{
int t1=Query(lz,tl,mid);
int t2=Query(rz,mid+,tr);
return max(t1,t2);
}
} void Solve(int x, int r)
{
vt.clear();
vt.push_back(x);
for(int i=; i*i<=x; i++)
if(x%i==)
{
vt.push_back(i);
vt.push_back(x/i);
}
for(int i=; i<vt.size(); i++)
{
int l=pre[ vt[i] ];
pre[ vt[i] ]=r;
if(l==-||l==r) continue;
Update(,,n,l,l,vt[i]);
}
} int main()
{
cin >> T;
while(T--)
{
cin >> n;
for(int i=; i<=n; i++) scanf("%d", a+i), pre[i]=-;
cin >> m;
for(int i=; i<=m; i++) f[i].id=i, scanf("%d%d",&f[i].l,&f[i].r);
sort(f+,f+m+);
for(int i=; i<=*n; i++) maxx[i]=, flag[i]=;
int i=, j=;
while(j<=m)
{
if(i<=f[j].r&&i<=n)
{
Solve(a[i],i);
i++;
}
else
{
if(f[j].l!=f[j].r)f[j].ans=Query(,,n,f[j].l,f[j].r);
else f[j].ans=;
j++;
}
}
sort(f+,f+m+,cmp);
for(int i=; i<=m; i++)
printf("%d\n",f[i].ans);
}
return ;
}

【HDU4630 No Pain No Game】 dp思想+线段树的离线操作的更多相关文章

  1. [DTOJ3996]:Lesson5!(DP+拓扑+线段树)

    题目描述 “最短的捷径就是绕远路,绕远路就是我最短的捷径” 转眼就$Stage\ X$了,$Stage\ X$的比赛路线可以看做一个$n$个点$m$条边的有向无环图,每条边长度都是$1$.杰洛$\cd ...

  2. Codeforces 675E Trains and Statistic(DP + 贪心 + 线段树)

    题目大概说有n(<=10W)个车站,每个车站i卖到车站i+1...a[i]的票,p[i][j]表示从车站i到车站j所需买的最少车票数,求所有的p[i][j](i<j)的和. 好难,不会写. ...

  3. LightOJ 1085(树状数组+离散化+DP,线段树)

    All Possible Increasing Subsequences Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format: ...

  4. BZOJ 1835: [ZJOI2010]base 基站选址(DP,线段树)

    可以很容易的写出dp方程: F[i][j]=min(F[l][j-1]+w[l][i])+c[i] (w[i][j]是从l+1到i-1这些点p里,所有满足d[p]+s[p]<d[i] & ...

  5. Codeforces 671D Roads in Yusland [树形DP,线段树合并]

    洛谷 Codeforces 这是一个非正解,被正解暴踩,但它还是过了. 思路 首先很容易想到DP. 设\(dp_{x,i}\)表示\(x\)子树全部被覆盖,而且向上恰好延伸到\(dep=i\)的位置, ...

  6. LOJ2537 PKUWC2018 Minimax 树形DP、线段树合并

    传送门 题意:自己去看 首先可以知道,每一个点都有几率被选到,所以$i$与$V_i$的关系是确定了的. 所以我们只需要考虑每一个值的取到的概率. 很容易设计出一个$DP$:设$f_{i,j}$为在第$ ...

  7. 洛谷P3928 Sequence2(dp,线段树)

    题目链接: 洛谷 题目大意在描述底下有.此处不赘述. 明显是个类似于LIS的dp. 令 $dp[i][j]$ 表示: $j=1$ 时表示已经处理了 $i$ 个数,上一个选的数来自序列 $A[0]$ 的 ...

  8. CF 463A && 463B 贪心 && 463C 霍夫曼树 && 463D 树形dp && 463E 线段树

    http://codeforces.com/contest/462 A:Appleman and Easy Task 要求是否全部的字符都挨着偶数个'o' #include <cstdio> ...

  9. [CERC2017]Intrinsic Interval——扫描线+转化思想+线段树

    [CERC2017]Intrinsic Interval https://www.luogu.org/blog/ywycasm/solution-p4747# 这种“好的区间”,见得还是比较多的了. ...

随机推荐

  1. 【转】Struts2解决表单重复提交问题

    用户重复提交表单在某些场合将会造成非常严重的后果.例如,在使用信用卡进行在线支付的时候,如果服务器的响应速度太慢,用户有可能会多次点击提交按钮,而这可能导致那张信用卡上的金额被消费了多次.因此,重复提 ...

  2. 【转】Java时间日期包 JodaTime

    maven: http://mvnrepository.com/artifact/joda-time/joda-time 1, 获取每天的零点 DateTime dt=new DateTime().w ...

  3. Liferay 6.2 改造系列之四:重新整理Application添加页面默认提供的Portlet清单

    经过2.3两步后,剩余Portlet已经不多,添加Application页面如下: 将用不到的Portlet隐藏起来:11   Portal目录 (Portal Directory) 将内嵌Protl ...

  4. JavaScript设计模式——方法的链式调用

    方法的链式调用: (function() { //私有类 function _$ (els) { this.elements = []; for(var i = 0, len = els.length ...

  5. Codeforces Round #355 (Div. 2)-C

    C. Vanya and Label 题目链接:http://codeforces.com/contest/677/problem/C While walking down the street Va ...

  6. CSS3-网站导航,transform,transition

    网站导航: 1.a:link    visited    hover   active的顺序是很重要的,如果改变顺序,则hover以及active的状态不起作用 2.<a href=" ...

  7. http://blog.csdn.net/chenleixing/article/details/43740759

    http://blog.csdn.net/chenleixing/article/details/43740759

  8. iOS学习35数据处理之文件读写

    1. 沙盒机制 1> 沙盒概述 每一个iOS应用程序都会为自己创建一个文件系统目录(文件夹), 这个独立.封闭.安全的空间,叫做沙盒 注:① 每一个应用程序都会拥有一个应用程序沙盒 ② 应用程序 ...

  9. iOS之05-三大特性之封装

    本次主要学习面向对象的三大特性:封装.继承和多态中的封装 封装 1. 好处 降低耦合率 可重复调用类中的属性 提高安全性,外部不能随便修改变量的值,保证了数据的安全性 2. set方法 1.作用:提供 ...

  10. BZOJ3257 : 树的难题

    设$f[x][i][j]$表示以$x$为根的子树,与$x$连通部分有$i$个黑点,$j$个白点,不联通部分都是均衡的最小代价.若$i>1$,则视作$1$:若$j>2$,则视作$2$. 然后 ...