HDU - 4630 No Pain No Game(离线线段树)

Posted mengx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU - 4630 No Pain No Game(离线线段树)相关的知识,希望对你有一定的参考价值。

No Pain No Game

题意:给出一个长度为n的1到n的排列 求区间两点gcd最大

思路:

因为题目没有更新 我们可以离线求解

对于每个查询按r排序

因为两点gcd一定会是两个数的约数 那么可以暴力插入a[i]的约数(当a[x]含有这个约数时 我们就能插入这个约数(x<i))

我们使用last数组维护上一次出现这个约数的位置即可

查询:我们就只需要查询l~r出现过最大的约数就行 

技术图片
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define inf 0x3f3f3f3f
const int maxn = 50000+5;
int Max[maxn<<2],a[maxn],last[maxn],ans[maxn];
struct node
    int l,r,id;
    bool friend operator<(const node u,const node v)
        return u.r<v.r;
    
p[maxn];
void build(int l,int r,int rt)
    Max[rt]=0;
    if(l==r) return ;
    int m=(l+r)>>1;
    build(lson);
    build(rson);

void push_up(int rt)
    Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);

void update(int l,int r,int rt,int L,int val)
    if(l==r)
        Max[rt]=max(Max[rt],val);
        return ;
    
    int m=(l+r)>>1;
    if(L<=m) update(lson,L,val);
    else update(rson,L,val);
    push_up(rt);

int query(int l,int r,int rt,int L,int R)
    if(L<=l&&r<=R) 
        return Max[rt];
    
    int m=(l+r)>>1;
    int ans=0;
    if(L<=m) ans=max(ans,query(lson,L,R));
    if(R>m)  ans=max(ans,query(rson,L,R));
    return ans;

int main()
    int t,n,m;
    scanf("%d",&t);
    while(t--)
        scanf("%d",&n);
        memset(last,0,sizeof(last));
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
            scanf("%d %d",&p[i].l,&p[i].r);
            p[i].id=i;
        
        sort(p+1,p+1+m);
        int j=1;
        build(1,n,1);
        for(int i=1;i<=n;i++)
            for(int k=1;k*k<=a[i];k++)
                if(a[i]%k==0)
                    if(last[k])
                        update(1,n,1,last[k],k);
                    if(last[a[i]/k]&&k!=a[i]/k)
                        update(1,n,1,last[a[i]/k],a[i]/k);
                    last[k]=i;
                    last[a[i]/k]=i;
                
            
            while(p[j].r<=i)
                if(j>m) break;
                if(p[j].l>p[j].r) ans[p[j].id]=0;
                else ans[p[j].id]=query(1,n,1,p[j].l,p[j].r);
                j++;
            
        
        for(int i=1;i<=m;i++)
            printf("%d\n",ans[i]);
        
    
    return 0;
View Code

 

以上是关于HDU - 4630 No Pain No Game(离线线段树)的主要内容,如果未能解决你的问题,请参考以下文章

hdu 4630 No Pain No Game 线段树离线处理

HDU - 4630 No Pain No Game(离线线段树)

hdu 4630 No Pain No Game (线段树+离线)

E - No Pain No Game 线段树

迟来的2021年终总结,2022已开始,Good luck every one! No pain No gain!

Python--关于 join 和 split