No Pain No Game Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1820 Accepted Submission(s): 778 链接:hdu 4630
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 a
1, a
2, ..., a
n.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 a
1, a
2, ..., a
n.
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
题意 给定N个数,这N个数是1~N的一种排列,然后给定Q个询问,每次询问一个区间[l,r],在[l,r]这个区间中求最大的gcd(a,b) , {l<=a<=b<=r}。 分析 这里我链接一个大牛的题解,我觉得他的题解讲得挺好的。我这里只补充一句,hdu有组数据是肯定错了, 1 1 1 1 1 正确答案是1才对。然而,杭电的数据确实0。。。 害得我WA了几个小时却不得其解。悲剧,呜呜呜~~~~~ /****************************>>>>HEADFILES<<<<****************************/
#include <set>
#include <map>
#include <list>
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <algorithm>
using namespace std;
/****************************>>>>>DEFINE<<<<<*****************************/
#define fst first
#define snd second
#define root 1,N,1
#define lrt rt<<1
#define rrt rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PB(a) push_back(a)
#define MP(a,b) make_pair(a,b)
#define CASE(T) for(scanf("%d",&T);T--;)
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w",stdout)
//#pragma comment(linker, "/STACK:1024000000,1024000000")
const int INF = 0x3f3f3f3f;
const int maxn = 50000 + 5;
/****************************>>>>SEPARATOR<<<<****************************/
struct Node
{
int l, r, id;
Node() {}
Node(int _l, int _r, int _id) : l(_l), r(_r), id(_id) {}
bool operator < (const Node& p) const
{
return r < p.r;
}
};
vector<Node> Asks;
int T, N, Q;
int a[maxn], pre[maxn], ans[maxn], segtree[maxn << 2];
vector<int> factor[maxn];
void init()
{
for(int i = 1; i < maxn; i++)
for(int j = i; j < maxn; j += i)
factor[j].PB(i);
}
inline void PushUp(const int& rt)
{
segtree[rt] = max(segtree[lrt], segtree[rrt]);
}
void Update(const int& pos, const int& val, int l, int r, int rt)
{
if(l == r)
{
segtree[rt] = max(segtree[rt], val);
return;
}
int mid = (l + r) >> 1;
if(pos <= mid) Update(pos, val, lson);
else Update(pos, val, rson);
PushUp(rt);
}
int Query(const int& L, const int& R, int l, int r, int rt)
{
if(L <= l && r <= R)
{
return segtree[rt];
// return max(1, segtree[rt]); 难道两个数的最大公约数不是一定大于1的么???下同
}
int mid = (l + r) >> 1, ret = 0; //1; 同上
if(L <= mid) ret = max(ret, Query(L, R, lson));
if(R > mid) ret = max(ret, Query(L, R, rson));
return ret;
}
int main()
{
// FIN;
init();
CASE(T)
{
scanf("%d", &N);
for(int i = 1; i <= N; i++) scanf("%d", &a[i]);
scanf("%d", &Q);
Asks.clear();
for(int i = 1, l, r; i <= Q; i++)
{
scanf("%d %d", &l, &r);
Asks.PB(Node(l, r, i));
}
sort(Asks.begin(), Asks.end());
memset(pre, -1, sizeof(pre));
memset(segtree, 0, sizeof(segtree));
int cnt = 0;
for(int i = 1; i <= N; i++)
{
for(int j = 0; j < factor[a[i]].size(); j++)
{
int &f = factor[a[i]][j];
if(pre[f] != -1)
{
Update(pre[f], f, root);
}
pre[f] = i;
}
while(cnt < Q && Asks[cnt].r == i)
{
int &l = Asks[cnt].l, &r = Asks[cnt].r, &id = Asks[cnt].id;
ans[id] = Query(l, r, root);
cnt++;
}
if(cnt >= Q) break;
}
for(int i = 1; i <= Q; i++) printf("%d\n", ans[i]);
}
return 0;
}
|