【线段树】 HDOJ 4630 No Pain No Game

来源:互联网 发布:辣条什么意思网络用语 编辑:程序博客网 时间:2024/05/03 03:43

离线处理, 把询问按左区间端点从大到小排序,然后点按从大到小的顺序插入这个数的约数。。。

#include <iostream>  #include <queue>  #include <stack>  #include <map>  #include <set>  #include <bitset>  #include <cstdio>  #include <algorithm>  #include <cstring>  #include <climits>  #include <cstdlib>#include <cmath>#include <time.h>#define maxn 50005#define maxm 100005#define eps 1e-10#define mod 3#define INF 1e17#define lowbit(x) (x&(-x))  #define ls o<<1#define rs o<<1 | 1#define lson o<<1, L, mid  #define rson o<<1 | 1, mid+1, R  typedef long long LL;//typedef int LL;using namespace std;struct node{    int a, b;    int id, ans;}op[maxn];int num[maxn];int pre[maxn];int value[maxn];int maxv[maxn<<2];int n, m, ql, qr, p, v;int cmp(node a, node b){    return a.a < b.a;}int cmp2(node a, node b){    return a.id < b.id;}void init(void){    memset(maxv, 0, sizeof maxv);    memset(value, 0, sizeof value);    for(int i = 1; i <= n; i++) pre[i] = n+1;}void read(void){    scanf("%d", &n);    for(int i = 1; i <= n; i++)        scanf("%d", &num[i]);    scanf("%d", &m);    for(int i = 1; i <= m; i++)        scanf("%d%d", &op[i].a, &op[i].b), op[i].id = i;}void pushup(int o){    maxv[o] = max(maxv[ls], maxv[rs]);}void updata(int o, int L, int R){    if(L == R) {        maxv[o] = v;        return;    }    int mid = (L+R)>>1;    if(p <= mid) updata(lson);    else updata(rson);    pushup(o);}int query(int o, int L, int R){    if(ql <= L && qr >= R) return maxv[o];    int mid = (L+R)>>1, ans = 0;    if(ql <= mid) ans = max(ans, query(lson));    if(qr > mid) ans = max(ans, query(rson));    return ans;}void debug(void){    for(int i = 1; i <= m; i++)        printf("AAA  %d  %d BB\n", op[i].a, op[i].b);}void work(void){    int pp = m, tmp;    sort(op+1, op+m+1, cmp);    for(int i = n; i >= 1; i--) {        tmp = sqrt(num[i]);        for(int j = 1; j <= tmp; j++) {            if(num[i]%j == 0) {                p = pre[j], pre[j] = i, v = j;                if(p <= n && value[p] < v) value[p] = v, updata(1, 1, n);                if(num[i]/j == j) continue;                p = pre[num[i]/j], pre[num[i]/j] = i, v = num[i]/j;                if(p <= n && value[p] < v) value[p] = v, updata(1, 1, n);            }        }        while(pp && op[pp].a == i) {            ql = 1, qr = op[pp].b;            op[pp--].ans = query(1, 1, n);        }    }    sort(op+1, op+m+1, cmp2);    for(int i = 1; i <= m; i++)        printf("%d\n", op[i].ans);}int main(void){    int _;    while(scanf("%d", &_)!=EOF) {        while(_--) {            read();            init();            work();        }    }    return 0;}


0 0