用纯C写的,WA得了40分,求帮忙看看代码很少
查看原帖
用纯C写的,WA得了40分,求帮忙看看代码很少
389268
LeM0NAdE楼主2021/8/21 17:07
//P3834 【模板】可持久化线段树 2(主席树)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int a[200009],dis[200009],n,m,k,b[200009];
int cmp(const void *p1,const void *p2){
    int* a=(int*)p1;
    int* b=(int*)p2;
    return *a-*b;
}
int getrank(int key){
    int l=1,r=n;
    while(l<=r){
        int mid = (l+r)>>1;
        if(dis[mid]> key){
            r=mid-1;
        }
        else if(dis[mid]<key){
            l = mid+1;
        }
        else if(dis[mid]==key){
            return mid;
        }
    }
    return -1;
}
struct Node
{
    int sum,l,r;//l,r分别代表左右子树,而不代表区间的左右端点
}hjt[200009*40];
int cnt,root[200009];

void insert(int l,int r,int pre,int *now,int val){//此处l,r代表区间的左右端点
    hjt[++cnt]=hjt[pre];
    *now = cnt;
    hjt[*now].sum++;
    if(l==r) return;
    int mid=(l+r)>>1;
    if(val<=mid){
        insert(l,mid,hjt[pre].l,&hjt[*now].l,val);
    }
    else{
        insert(mid+1,r,hjt[pre].r,&hjt[*now].r,val);
    }
}

int query(int l,int r,int L,int R,int k){//L表示L-1版本的权值线段树的当前节点{
    if(l==r) return l;
    int mid = (l+r)>>1;
    int tmp=hjt[hjt[R].l].sum-hjt[hjt[L].l].sum;
    if(k<=tmp){
        return query(l,mid,hjt[L].l,hjt[R].l,k);
    }
    else{
        return query(mid+1,r,hjt[L].r,hjt[R].r,k-tmp);
    }
}
int main(){
    int k,l,r,i,j;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++){
        scanf("%d",&a[i]);
        b[i]=a[i];
    }
    qsort(a+1,n,sizeof(a[0]),cmp);
    dis[1]=a[1];
    for(i=j=1;i<n;i++){
        if(a[i]!=a[i+1]){
            dis[++j]=a[i+1];
        }
    }
    for(i=1;i<=n;i++){
        insert(1,j,root[i-1],&root[i],getrank(b[i]));
    }
    while(m--){
        scanf("%d%d%d",&l,&r,&k);
        int ans = query(1,j,root[l-1],root[r],k);
        ans = dis[ans];
        printf("%d\n",ans);
    }
    return 0;
}

2021/8/21 17:07
加载中...