求更优做法
  • 板块学术版
  • 楼主Zq_water
  • 当前回复10
  • 已保存回复11
  • 发布时间2024/1/14 11:24
  • 上次更新2024/1/14 13:50:45
查看原帖
求更优做法
895435
Zq_water楼主2024/1/14 11:24

loj 6285

给定一个长度为n的序列a,之后有n次询问,每次询问[l,r]区间中的最小众数,蒟蒻的方法被卡了,求优化/更有解法

我的做法是普通莫队+权值线段树

#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
 
int n,block,a[maxn],b[maxn],A[maxn],mp[maxn],ans[maxn];
struct Query{int l,r,id;}q[maxn];
inline int read(){
    register int x=0,f=1;register char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
struct Segment_Tree{
    struct Tree{int l,r,maxx,id;}t[maxn<<2];
    inline void push_up(int u){
        if(t[u<<1].maxx>t[u<<1|1].maxx) t[u].maxx=t[u<<1].maxx,t[u].id=t[u<<1].id;
        else if(t[u<<1].maxx<t[u<<1|1].maxx) t[u].maxx=t[u<<1|1].maxx,t[u].id=t[u<<1|1].id;
        else t[u].maxx=t[u<<1].maxx,t[u].id=min(t[u<<1].id,t[u<<1|1].id);
    }
    inline void build(int u,int l,int r){
        t[u].l=l,t[u].r=r,t[u].id=-2e9;
        if(l==r){t[u].id=l;return;}
        int mid=l+r>>1;
        build(u<<1,l,mid),build(u<<1|1,mid+1,r);
        push_up(u);
    }
    inline void modify(int u,int pos,int x){
//      cout<<u<<" "<<t[u].l<<" "<<t[u].r<<endl;
        if(t[u].l==t[u].r){t[u].maxx+=x;return;}
        int mid=t[u].l+t[u].r>>1;
        if(pos<=mid) modify(u<<1,pos,x);
        if(pos>mid) modify(u<<1|1,pos,x);
        push_up(u);
    }
    inline pair<int,int> query(int u,int l,int r){
        if(l<=t[u].l&&t[u].r<=r) return {t[u].id,t[u].maxx};
        int mid=t[u].l+t[u].r>>1;
        pair<int,int> ans={-1,0};
        if(r<=mid) ans=query(u<<1,l,r);
        else if(l>mid) ans=query(u<<1|1,l,r);
        else if(l<=mid&&r>mid){
            pair<int,int> ans1=query(u<<1,l,r),ans2=query(u<<1|1,l,r);
            if(ans1.second<ans2.second) ans=ans2;
            else if(ans1.second>ans2.second) ans=ans1;
            else ans={min(ans1.first,ans2.first),ans1.second};
        }
        return ans;
    }
    void dfs(int u){
        if(t[u].l==t[u].r){
            cout<<t[u].id<<" "<<t[u].maxx<<endl;
            return; 
        }
        dfs(u<<1),dfs(u<<1|1);
    }
}tr;
 
inline bool cmp(Query x,Query y){
    if(x.l/block==y.l/block) return x.r<y.r;
    return x.l/block<y.l/block;
}
inline void add(int x){tr.modify(1,A[x],1);}
inline void del(int x){tr.modify(1,A[x],-1);}
int main(){
    n=read(),block=sqrt(n);
    for(int i=1;i<=n;i++) a[i]=read(),b[i]=a[i];
    sort(b+1,b+n+1);
    int m=unique(b+1,b+n+1)-b-1;
    for(register int i=1;i<=n;i++) A[i]=lower_bound(b+1,b+m+1,a[i])-b,mp[A[i]]=a[i];//离散化后数组A[i] 
    for(register int i=1;i<=n;i++) q[i].l=read(),q[i].r=read(),q[i].id=i; 
    sort(q+1,q+n+1,cmp);
    tr.build(1,1,n);
    int l=1,r=0;
    for(register int i=1;i<=n;i++){
        while(l<q[i].l) del(l++);
        while(l>q[i].l) add(--l);
        while(r<q[i].r) add(++r);
        while(r>q[i].r) del(r--);
//      cout<<"dfs "<<i<<": "<<endl; 
//      tr.dfs(1);
//      puts("");
        ans[q[i].id]=mp[tr.query(1,1,n).first];
    }
    for(int i=1;i<=n;i++)printf("%d\n",ans[i]);
    return 0;
}
2024/1/14 11:24
加载中...