hdu 5857 Median (主席树写法)

来源:互联网 发布:崩坏学园2狗章伤害算法 编辑:程序博客网 时间:2024/06/05 15:03

题意:

给出一个有序的数列.
求由 A[l1]~A[r1] 与 A[l2]~A[r2] 组成的新序列的中位数.

题解:

比赛时没看见有序,直接套了主席树,越写越乱,赛后改一下过了


#include <set>#include <map>#include <stack>#include <queue>#include <deque>#include <cmath>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF  0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-9#define maxn 100100#define MOD 1000000007const int MAXN = 100010;const int M = MAXN * 30;int n,q,m,tot;int a[MAXN], t[MAXN];int T[M], lson[M], rson[M], c[M];void Init_hash(){    for(int i = 1; i <= n; i++)        t[i] = a[i];    sort(t+1,t+1+n);    m = unique(t+1,t+1+n)-t-1;}int build(int l,int r){    int root = tot++;    c[root] = 0;    if(l != r)    {        int mid = (l+r)>>1;        lson[root] = build(l,mid);        rson[root] = build(mid+1,r);    }    return root;}int Hash(int x){    return lower_bound(t+1,t+1+m,x) - t;}int update(int root,int pos,int val){    int newroot = tot++, tmp = newroot;    c[newroot] = c[root] + val;    int l = 1, r = m;    while(l < r)    {        int mid = (l+r)>>1;        if(pos <= mid)        {            lson[newroot] = tot++;            rson[newroot] = rson[root];            newroot = lson[newroot];            root = lson[root];            r = mid;        }        else        {            rson[newroot] = tot++;            lson[newroot] = lson[root];            newroot = rson[newroot];            root = rson[root];            l = mid+1;        }        c[newroot] = c[root] + val;    }    return tmp;}int query(int lt1,int rt1,int lt2,int rt2,int k){    int l = 1, r = m;    while( l < r)    {        int mid = (l+r)>>1;        //printf("%d %d %d %d %d\n",l,r,left_root,right_root,k);        if(c[lson[lt1]]-c[lson[rt1]]+c[lson[lt2]]-c[lson[rt2]] >= k )        {            r = mid;            lt1 = lson[lt1];            rt1 = lson[rt1];            lt2 = lson[lt2];            rt2 = lson[rt2];        }        else        {            l = mid + 1;            k -= c[lson[lt1]]-c[lson[rt1]]+c[lson[lt2]]-c[lson[rt2]];            lt1 = rson[lt1];            rt1 = rson[rt1];            lt2 = rson[lt2];            rt2 = rson[rt2];        }    }    return l;}int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int tt;    scanf("%d",&tt);    while(tt--)    {        scanf("%d%d",&n,&q);        tot = 0;        for(int i = 1; i <= n; i++)            scanf("%d",&a[i]);        Init_hash();        T[n+1] = build(1,m);        for(int i = n; i ; i--)        {            int pos = Hash(a[i]);            T[i] = update(T[i+1],pos,1);        }        while(q--)        {            int l1,r1,l2,r2;            scanf("%d%d%d%d",&l1,&r1,&l2,&r2);            int len = r1 - l1 + 1 + r2 - l2 + 1;            if(len & 1)            {                len = len / 2 + 1;                printf("%.1f\n",1.0*t[query(T[l1],T[r1+1],T[l2],T[r2+1],len)]);            }            else            {                len = len / 2;                printf("%.1f\n",0.5*t[query(T[l1],T[r1+1],T[l2],T[r2+1],len)]+0.5*t[query(T[l1],T[r1+1],T[l2],T[r2+1],len+1)]);            }        }    }    return 0;}



0 0
原创粉丝点击