hdu 4630 No Pain No Game(线段树+离线操作)
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
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.
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.
1
10
8 2 4 9 5 7 10 6 1 3
5
2 10
2 4
6 9
1 4
7 10
5
2
2
4
3
pid=5282" target="_blank" style="color:rgb(26,92,200); text-decoration:none">5282
5280pid=5279" target="_blank" style="color:rgb(26,92,200); text-decoration:none">5279
5278题意: 有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(线段树+离线操作)的更多相关文章
- HDU - 4630 No Pain No Game (线段树 + 离线处理)
id=45786" style="color:blue; text-decoration:none">HDU - 4630 id=45786" style ...
- 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 ...
- HDU 4630 No Pain No Game (线段树+离线)
题目大意:给你一个无序的1~n的排列a,每次询问[l,r]之间任取两个数得到的最大gcd是多少 先对所有询问离线,然后把问题挂在区间的左端点上(右端点也行) 在预处理完质数,再处理一个next数组,表 ...
- hdu 4630 No Pain No Game 线段树离线处理
题目链接 求出一个区间内任意两个数的gcd的最大值. 先将询问读进来然后按r值排序. 将每一个数因数分解, 对每一个因子x, 如果pre[x]!=-1, 那么就更新update(pre[x], x, ...
- hdu 5274 Dylans loves tree(LCA + 线段树)
Dylans loves tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- HDU 3074.Multiply game-区间乘法-线段树(单点更新、区间查询),上推标记取模
Multiply game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)
HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址:HDU 1394 Minimum Inversion Number 题意: 给一个序列由 ...
- E - No Pain No Game 线段树 离线处理 区间排序
E - No Pain No Game HDU - 4630 这个题目很好,以后可以再写写.这个题目就是线段树的离线写法,推荐一个博客:https://blog.csdn.net/u01003321 ...
- hdu 1556:Color the ball(线段树,区间更新,经典题)
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
随机推荐
- html模板引擎jade的使用
jade语法: #{xxx} //嵌入数据 p= xxx //嵌入数据 p #{xx} //嵌入数据 标签 html // 翻译为<html></html> div#test ...
- rootkit 内核函数hook
转自:https://0x90syntax.wordpress.com/2016/02/21/suterusu-rootkitx86%e4%b8%8earm%e7%9a%84%e5%86%85%e8% ...
- screenshoter 連續截圖工具
https://pcrookie.com/?p=993 顯示 mouse 設定 Settings -> Saving -> Display mouse cursor
- xpath测试工具 xpath调试工具
其实这个工具没什么介绍的了 因为目前有项目中需要到了xpath语法,然后呢,有没有什么好的工具 大部分都是联网的,个人比较喜欢离线的工具包 所以顺手就写了一个小工具来测试xpath语法的正确性 so, ...
- 关于js拖拽功能,拖拽元素的position:fixed;left:0;right:0;样式引起左右拖动元素会出现落后鼠标移动距离的问题
被拖拽元素的样式如果为:position:fixed;left:0;right:0;(当时是为了让fixed定位的元素水平居中加的left:0;right:0;避免js动态计算定位的麻烦)时左右拖动会 ...
- mysql 取消命令行继续编辑
mysql> create database mingongge defa\c#回车 置空mysql> 加一个\c cancel 编辑命令 回车
- functools模块方法学习(1):partial
函数的partial应用 典型的,函数在执行时,要带上所有必要的参数进行调用.然后,有时参数可以在函数被调用之前提前获知.这种情况下,一个函数有一个或多个参数预先就能用上,以便函数能用更少的参数进行调 ...
- 想转行做web前端工程师,必学这6大技能
web前端工程师是近几年才发展出来的新兴职业,也是目前火爆且高薪的职业.大需求的市场环境下,出现了越来越多的人群转行做web前端工程师,如设计师.后台程序员.网虫.大学其他专业.策划.编辑等等. 要学 ...
- ES6新特性及用法笔记
1.新增数据类型Symbol.[Number.Boolean.Symbol.Null.Undefined.Object] Symbol类型的值通过Symbol函数生成,相同的Symbol函数返回的值 ...
- [BZOJ1038][ZJOI2008]瞭望塔(半平面交)
1038: [ZJOI2008]瞭望塔 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2999 Solved: 1227[Submit][Statu ...