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. [ CodeVS冲杯之路 ] P3027

    不充钱,你怎么AC? 题目:http://codevs.cn/problem/3027/ 显然是DP题,先按线段的右端点升序排序 设 f[i] 为dp到第 i 个线段时最大的价值 目标状态为 max( ...

  2. 翻煎饼_简单模拟_C++

    一.题目描述(懒人可直接跳过看题目概述) 题目来源: SWUST OJ  题目0254 http://acm.swust.edu.cn/problem/0254/ 二.问题概述 给出一列数,每次可将包 ...

  3. windows技术

    鼠标右键菜单中没有新建文本文件怎么办? http://jingyan.baidu.com/article/046a7b3e1d737bf9c27fa9f7.html

  4. suse10与suse11连接Xmanager的配置

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://feidandelion.blog.51cto.com/1050439/42217 ...

  5. Android 利用 AsyncTask 异步读取网络图片

    1.新建Android工程AsyncLoadPicture 新建布局文件activity_main.xml主界面为一个GridView,还有其子项布局文件gridview_item.xml 2.功能主 ...

  6. 使用iSCSI Target创建集中式安全存储(一)

    iSCSI 是一种块级别的协议,用于通过TCP/IP网络共享原始存储设备,可以用已经存在的IP和以太网如网卡.交换机.路由器等通过iSCSI协议共享和访问存储.iSCSI target是一种由远程iS ...

  7. 基于django rest framework的mock server实践

    网上找了一下mock server的实现,发现python的基本都是基于flask来实现的,因最近在学django,就尝试用drf实现了下: A brief introduction of sui_m ...

  8. A/B Testing with Practice in Python (Part Two)

    This is the second part of A/B testing notes, which contains the practical issues and alternatives o ...

  9. poj2104(划分树模板)

    poj2104 题意 给出一个序列,每次查询一个区间,要求告诉这个区间排序后的第k个数. 分析 划分树模板,O(mlogn). 建树.根据排序之后的数组,对于一个区间,找到中点的数,将整个区间分为左右 ...

  10. poj1743(后缀数组)

    poj1743 题意 给出一个数字序列(串),现在要去寻找一个满足下列条件的子串: 长度不小于 5 存在重复的子串(如果把一个子串的所有数字都加上或减去一个值,与另一子串的数字对应相同,我们称它们重复 ...