[bzoj2223][Coci 2009]PATULJCI 主席树

来源:互联网 发布:mac跳过打开软件验证 编辑:程序博客网 时间:2024/06/11 04:02

2223: [Coci 2009]PATULJCI

Time Limit: 10 Sec  Memory Limit: 259 MB
[Submit][Status][Discuss]

Description

Input

Output

10 3 1 2 1 2 1 2 3 2 3 3 8 1 2 1 3 1 4 1 5 2 5 2 6 6 9 7 10

Sample Input

no
yes 1
no
yes 1
no
yes 2
no
yes 3

Sample Output

HINT

Notice:输入第二个整数是序列中权值的范围Lim,即1<=ai(1<=i<=n)<=Lim。

1<=Lim<=10000

Source

跟3524一道题
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>using namespace std;const int N = 500000 + 5;int n,m,cnt,id,a[N],p[N],num[N],v[N],ans,lim;int sum[N*20],ls[N*20],rs[N*20],root[N];bool cmp( int x, int b ){ return a[x] < a[b]; }void build( int &k, int l, int r, int x ){ls[++id] = ls[k]; rs[id] = rs[k]; sum[id] = sum[k]+1; k = id;if( l == r ) return ;int mid = (l+r)>>1;if( x <= mid ) build( ls[k], l, mid, x );else build( rs[k], mid+1, r, x );}int query( int x, int y, int l, int r, int k ){if( l == r ) return l;int mid = (l+r)>>1;int sl = sum[ls[y]]-sum[ls[x]], sr = sum[rs[y]]-sum[rs[x]];if( sl >= k ) return query( ls[x], ls[y], l, mid, k );else if( sr >= k ) return query( rs[x], rs[y], mid+1, r, k );else return 0;}int main(){scanf("%d%d", &n, &lim);for( int i = 1; i <= n; i++ ) scanf("%d", &a[i]), p[i]=i;std::sort(p+1,p+n+1,cmp);for( int i = 1; i <= n; i++ ) num[p[i]] = (a[p[i]] != a[p[i-1]]) ? ++cnt : cnt;for( int i = 1; i <= n; i++ ) v[num[i]] = a[i];for( int i = 1; i <= n; i++ ){root[i] = root[i-1];build( root[i], 1, cnt, num[i] );}scanf("%d", &m);for( int i = 1,x,y; i <= m; i++ ){scanf("%d%d", &x, &y);ans = query(root[x-1],root[y],1,cnt,(y-x+1)/2+1);if( !v[ans] ) puts("no");else {printf("yes %d\n",v[ans]);}}return 0;}