No Pain No Game

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 1769    Accepted Submission(s): 748

Problem Description
Life is a game,and you lose it,so you suicide.

But you can not kill yourself before you solve this problem:

Given you a sequence of number a1, a2, ..., an.They are also a permutation of 1...n.

You need to answer some queries,each with the following format:

If we chose two number a,b (shouldn't be the same) from interval [l, r],what is the maximum gcd(a, b)? If there's no way to choose two distinct number(l=r) then the answer is zero.
 
Input
First line contains a number T(T <= 5),denote the number of test cases.

Then follow T test cases.

For each test cases,the first line contains a number n(1 <= n <= 50000).

The second line contains n number a1, a2, ..., an.

The third line contains a number Q(1 <= Q <= 50000) denoting the number of queries.

Then Q lines follows,each lines contains two integer l, r(1 <= l <= r <= n),denote a query.
 
Output
For each test cases,for each query print the answer in one line.
 
Sample Input
1
10
8 2 4 9 5 7 10 6 1 3
5
2 10
2 4
6 9
1 4
7 10
 
Sample Output
5
2
2
4
3
 
Author
WJMZBMR
 
Source
 
Recommend
 

题意: 有N个数。 是 1~N的一个排列。有M个询问, 每次询问一个区间, 问从这个区间中,取两个数的最大的最大公约数。

题解:先把查询按右区间升序排序。在将数组按顺序插入,记录当前这个数的因子出现的位置,假设之前有出现则代表这两个因子出现的

位置之间有两个数的公共约数是它,用线段树维护区间约数最大值就可以。

#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<vector>
#define lson idx<<1,l,mid
#define rson idx<<1|1,mid+1,r
#define N 50050
#define lc idx<<1
#define rc idx<<1|1 using namespace std; int n,q,flag;
int a[N],tree[N*4];
int L[N],R[N];
int first[N],ans[N];
vector<int>vec; struct node {
int id;
int l,r;
} Q[N]; bool cmp(node a,node b) {
if(a.r==b.r)
return a.l<b.l;
return a.r<b.r;
} ///求全部因子
void FJ(int x) {
vec.clear();
for(int i=1; i*i<=x; i++) {
if(x%i==0) {
vec.push_back(i);
if(x/i!=i)
vec.push_back(x/i);
}
}
} void push_up(int idx) {
tree[idx]=max(tree[lc],tree[rc]);
} void build(int idx,int l,int r) {
tree[idx]=0;
if(l==r) {
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
} void update(int idx,int l,int r,int x,int v) { //x处的值改为v
if(l==r) {
if(tree[idx]<v)
tree[idx]=v;
return;
}
int mid=(l+r)>>1;
if(x<=mid)update(lson,x,v);
else update(rson,x,v);
push_up(idx);
} int query(int idx,int l,int r,int x,int y) {
if(l>=x&&y>=r) {
return tree[idx];
}
int ans=0;
int mid=(l+r)>>1;
if(x<=mid) {
ans=max(ans,query(lson,x,y));
}
if(y>mid) {
ans=max(ans,query(rson,x,y));
}
return ans;
} void debug() {
for(int i=0; i<vec.size(); i++) {
printf("%d ",vec[i]);
}
cout<<endl;
} int main() {
//freopen("test.in","r",stdin);
int t;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
for(int i=1; i<=n; i++) {
scanf("%d",&a[i]);
}
scanf("%d",&q);
for(int i=1; i<=q; i++) {
scanf("%d%d",&Q[i].l,&Q[i].r);
Q[i].id=i;
}
sort(Q+1,Q+1+q,cmp);
memset(first,0,sizeof first);
memset(L,0,sizeof L);
memset(R,0,sizeof R);
build(1,1,n);
///预处理同样有区间的左右区间
int f=1;
L[Q[f].r]=f;
R[Q[f].r]=f;
for(int i=1; i<=q;) {
while(Q[i].r==Q[f].r&&i<=q) {
i++;
}
L[Q[f].r]=f;
R[Q[f].r]=i-1;
f=i;
}
for(int i=1; i<=n; i++) {
//FJ(a[i]);
//debug();
int xx=a[i];
for(int k=1; k*k<=xx; k++) {
if(xx%k==0) {
if(!first[k]) {
first[k]=i;
} else {
update(1,1,n,first[k],k);
first[k]=i;
}
int kk=xx/k;
if(k!=kk) {
if(!first[kk]) {
first[kk]=i;
} else {
update(1,1,n,first[kk],kk);
first[kk]=i;
}
}
}
}
int x=L[i],y=R[i];
if(x==0||y==0)continue;
for(int j=x; j<=y; j++) {
int k=Q[j].l;
if(k==i) {
ans[Q[j].id]=0;
} else {
ans[Q[j].id]=query(1,1,n,k,i);
}
}
if(y==q)break;
}
for(int i=1; i<=q; i++) {
printf("%d\n",ans[i]);
}
}
return 0;
}

hdu 4630 No Pain No Game(线段树+离线操作)的更多相关文章

  1. HDU - 4630 No Pain No Game (线段树 + 离线处理)

    id=45786" style="color:blue; text-decoration:none">HDU - 4630 id=45786" style ...

  2. HDU 4630 No Pain No Game 线段树 和 hdu3333有共同点

    No Pain No Game Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  3. HDU 4630 No Pain No Game (线段树+离线)

    题目大意:给你一个无序的1~n的排列a,每次询问[l,r]之间任取两个数得到的最大gcd是多少 先对所有询问离线,然后把问题挂在区间的左端点上(右端点也行) 在预处理完质数,再处理一个next数组,表 ...

  4. hdu 4630 No Pain No Game 线段树离线处理

    题目链接 求出一个区间内任意两个数的gcd的最大值. 先将询问读进来然后按r值排序. 将每一个数因数分解, 对每一个因子x, 如果pre[x]!=-1, 那么就更新update(pre[x], x, ...

  5. hdu 5274 Dylans loves tree(LCA + 线段树)

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  6. HDU 3074.Multiply game-区间乘法-线段树(单点更新、区间查询),上推标记取模

    Multiply game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  7. HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)

    HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址:HDU 1394 Minimum Inversion Number 题意:  给一个序列由 ...

  8. E - No Pain No Game 线段树 离线处理 区间排序

    E - No Pain No Game  HDU - 4630 这个题目很好,以后可以再写写.这个题目就是线段树的离线写法,推荐一个博客:https://blog.csdn.net/u01003321 ...

  9. hdu 1556:Color the ball(线段树,区间更新,经典题)

    Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

随机推荐

  1. bzoj [Noi2008] 1061 志愿者招募 单纯形

    [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 5437  Solved: 3267[Submit][Status][Di ...

  2. ES6特性以及代码demo

    块级作用域let if(true){ let fruit = ‘apple’; } consoloe.log(fruit);//会报错,因为let只在if{ }的作用域有效,也就是块级作用域 恒量co ...

  3. Nano

    Nano命令指南 今天在输命令时,无意中输入了nano,对这个命令不太熟悉,结果不知道如何才能退出,保存,赶快查了一下资料,原来是这样的啊. 打开文件与新建文件 使用nano打开或新建文件,只需键入: ...

  4. Winform 在DataGrid中签入Combo

    背景 最近看了Winform在DataGrid中怎么嵌入Combo,想到平时项目中写到的一些临时小工具,经常用配置参数,有些配置是简单的地址或文本,有些则是类似1代表SQL,2代表Oracle等.于是 ...

  5. JUnit--BeforeClass、AfterClass、Before、After示例

    JUnit 4 使用 Java 5 中的注解(annotation),以下是JUnit 4 常用的几个 annotation 介绍@Before:初始化方法@After:释放资源@Test:测试方法, ...

  6. laravel按月/时间区间查询数据

    public function payRollList($time) { $member_phone = Session::get(phone'); $engineer = Engineer::get ...

  7. DRF的版本和认证

    DRF的版本 版本控制是做什么用的, 我们为什么要用 首先我们要知道我们的版本是干嘛用的呢~~大家都知道我们开发项目是有多个版本的~~ 当我们项目越来越更新~版本就越来越多~~我们不可能新的版本出了~ ...

  8. hadoop之linux常用命令

    Linux的命令后面会有命令选项,有的选项还有选项值.选项的前面有短横线“-”,命令.选项.选项值之间使用空格隔开.有的命令没有选项,会有参数.选项是命令内置的功能,参数是用户提供的符合命令格式的内容 ...

  9. Python与数据库[2] -> 关系对象映射/ORM[3] -> sqlalchemy 的声明层 ORM 访问方式

    sqlalchemy的声明层ORM访问方式 sqlalchemy中可以利用声明层进行表格类的建立,并利用ORM对象进行数据库的操作及访问,另一种方式为显式的 ORM 访问方式. 主要的建立步骤包括: ...

  10. HDU 6396 Swordsman --------2018 Multi-University Training Contest 7 (模拟+读入挂)

    原题地址: 打怪升级 一开始有N个怪物:主角有K个能力:只有K个能力都击败怪物才能斩杀怪物并获得K个能力的增值:问最多能杀几个怪物: 做法: 用优先队列把怪物能力装进去:能力小放前面: 最重要的是数据 ...