多校第三场——hdu4631——离线
2013-07-31 15:18
190 查看
题意:询问一个序列的某一个子区间中的最大的gcd的值。
这题关键一点是把最大的gcd转换为最大出现过多次的约数,这样就可以转化为一个求区间最大值的问题了。
我从后往前扫一遍原序列,同时记录每一个约数出现的最靠左的位置。每次处理序列中的一个数时,对这个数所有的约数,找到该约数出现的最靠左的位置,并在树状数组中更新该位置的值。在我们处理序列的第i的元素的时候,对于起始位置在i的询问,我们只要求出树状数组[0, r]区间的最大值就可以了。
这题关键一点是把最大的gcd转换为最大出现过多次的约数,这样就可以转化为一个求区间最大值的问题了。
我从后往前扫一遍原序列,同时记录每一个约数出现的最靠左的位置。每次处理序列中的一个数时,对这个数所有的约数,找到该约数出现的最靠左的位置,并在树状数组中更新该位置的值。在我们处理序列的第i的元素的时候,对于起始位置在i的询问,我们只要求出树状数组[0, r]区间的最大值就可以了。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; const int maxn = 50000 + 10; int num[maxn], n; int hash[maxn]; int c[maxn]; int ans[maxn], nq; struct query { int l, r, ord; bool operator < (const query & rhs) const { return l > rhs.l; } }q[maxn]; inline int lowbit(int t) { return t & (-t); } inline void add(int pos, int t) { while(pos <= n) { c[pos] = max(c[pos], t); pos += lowbit(pos); } } inline int sum(int pos) { int s = 0; while(pos > 0) { s = max(s, c[pos]); pos -= lowbit(pos); } return s; } void prework() { scanf("%d", &n); for(int i = 1; i <= n; ++i) c[i] = 1; memset(hash, 0, sizeof(hash)); for(int i = 1; i <= n; ++i) scanf("%d", num + i); scanf("%d", &nq); for(int i = 1; i <= nq; ++i) { scanf("%d %d", &q[i].l, &q[i].r); q[i].ord = i; } sort(q + 1, q + nq + 1); } void solve() { int c = 1; for(int i = n; i > 0; --i) { for(int j = 1; j * j <= num[i]; ++j) { if(num[i] % j == 0) { if(hash[j] != 0) add(hash[j], j); hash[j] = i; if(j * j != num[i]) { int tmp = num[i] / j; if(hash[tmp] != 0) add(hash[tmp], tmp); hash[tmp] = i; } } } while(q[c].l == i) { ans[q[c].ord] = sum(q[c].r); if(q[c].l == q[c].r) ans[q[c].ord] = 0; c++; } } for(int i = 1; i <= nq; ++i) printf("%d\n", ans[i]); } int main() { freopen("in.txt", "r", stdin); int t; cin >> t; while(t--) { prework(); solve(); } return 0; }
相关文章推荐
- 2013 多校第三场 hdu 4631 Sad Love Story
- hdu 4323 Magic Number 2012多校训练第三场1004题 BK树
- HDU 4622 多校第三场1002 后缀自动机
- 2017 多校训练第三场 HDU 6060 RXD and dividing
- 多校第三场 1006 hdu 5323 Solve this interesting problem(dfs)
- (2017多校训练第三场)HDU - 6063 RXD and math 找规律 + 快速幂
- hdu 4891 The Great Pan 2014多校联合第三场
- 多校第一场 1006 hdu 5293 Tree chain problem(离线LCA+时间戳+树形dp)
- hdu 4888 2014多校第三场1002 Redraw Beautiful Drawings 网络流
- hdu 4630 多校第二场 树状数组,离线处理
- 2017 多校训练第三场 HDU 6066 RXD's date
- HDU 4631 Sad Love Story (2013多校3 1011题 平面最近点对+爆搞)
- HDU 4638 Group (2013多校4 1007 离线处理+树状数组)
- HDU 4638 多校第四场1007 离线询问,树状数组||线段树维护
- hdu 5316 Magician(2015多校第三场第1题)线段树单点更新+区间合并
- 多校第三场 1005 HDU 6060 思维贪心+dfs+一维建树
- HDU 5317(2015多校第三场1002)
- hdu 5317 RGCDQ (2015多校第三场第2题)素数打表+前缀和相减求后缀(DP)
- HDU 多校联合第三场
- 2017 多校训练第三场 HDU 6058 Kanade's sum