萌新刚学oi,最后几个点wa了求调
查看原帖
萌新刚学oi,最后几个点wa了求调
589600
AH20楼主2022/9/21 15:28

我的思路就是先求出这个区间的中位数,然后再求这个中位数的出现次数,如果出现次数大于n/2的话输出这个数,否则输出0

#include<bits/stdc++.h>
using namespace std;
const int maxm=5e5+10;
struct Persistent_Segment_Tree{
     int lch[maxm*21],rch[maxm*21],tot;
     int sum[maxm*21];
     inline void init(){
        tot=0;
     }
     inline void build(int &root,int L,int R){
         root=++tot;
          if(L==R){
            return;
          }
          int mid=(L+R)>>1;
          build(lch[root],L,mid);
          build(rch[root],mid+1,R);
     }
     inline void Copy(int from,int to){
           lch[to]=lch[from];
           rch[to]=rch[from];
           sum[to]=sum[from];
     }
     inline void update(int &root,int old,int cl,int cr,int l,int r,int x){
          root=++tot;
          Copy(old,root);
          sum[root]+=x*(r-l+1);
          if(l==cl&&r==cr) return;
          int mid=(cl+cr)>>1;
          if(r<=mid) update(lch[root],lch[root],cl,mid,l,r,x);
          else update(rch[root],rch[root],mid+1,cr,l,r,x);
     }
     inline int query(int s,int t,int L,int R,int k){
        if(L==R) return L;
        int mid=(L+R)>>1;
        if(k<=sum[lch[t]]-sum[lch[s]]){
            return query(lch[s],lch[t],L,mid,k);
        }
        else{
            return query(rch[s],rch[t],mid+1,R,k-(sum[lch[t]]-sum[lch[s]]));
        }
     }
     inline int qsum(int s,int t,int L,int R,int x){
            if(L==R) return sum[t]-sum[s];
            int mid=(L+R)>>1;
            if(x<=mid) return qsum(lch[s],lch[t],L,mid,x);
            else return qsum(rch[s],rch[t],mid+1,R,x);
     }//查询区间[s,t]中数字x出现的次数
     //求区间第k小
     //s和t反应的是根节点的位置(相当于一个)
     //L,R为当前s、t代表的区间端点值
};
Persistent_Segment_Tree seg;
int n,m;
int root[maxm];
int main(){
    scanf("%d%d",&n,&m);
    seg.init();
    seg.build(root[0],1,n);
    for(int i=1;i<=n;i++){
        int x;
        scanf("%d",&x);
        seg.update(root[i],root[i-1],1,n,x,x,1);
    }
    while(m--){
        int L,R,k;
        scanf("%d%d",&L,&R);k=(R-L+1)/2+1;
        int num=seg.query(root[L-1],root[R],1,n,k);
        int cnt=seg.qsum(root[L-1],root[R],1,n,num);
        if(cnt>=k) printf("%d\n",num);
        else printf("0\n");
    }
    return 0;
}
2022/9/21 15:28
加载中...