zoukankan      html  css  js  c++  java
  • [bzoj3524/2223][Poi2014]Couriers_主席树

    Couriers bzoj-3524 Poi-2014

    题目大意:给定n个数的序列,询问区间内是否存在一个在区间内至少出现了(区间长度>>1)次的数。如果有,输出该数,反之输出0。

    注释:$1le n,mle 5cdot 10^5$。


    想法:主席树裸题。

    主流做法就是弄一个Existence数组询问有没有这样的数,然后查询区间中位数即可。

    但是可以在query的时候强行查询,因为没有输出0,直接输出即可。

    最后,附上丑陋的代码... ...

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #define N 500010
    using namespace std;
    int cnt[N<<5],ls[N<<5],rs[N<<5],tot;
    int a[N],b[N],root[N];
    int build(int l,int r)
    {
    	int pos=++tot,mid=(l+r)>>1;
    	if(l==r) return pos;
    	ls[pos]=build(l,mid); rs[pos]=build(mid+1,r);
    	return pos;
    }
    int update(int pre,int l,int r,int k)
    {
    	int pos=++tot,mid=(l+r)>>1;
    	cnt[pos]=cnt[pre]+1;
    	ls[pos]=ls[pre]; rs[pos]=rs[pre];
    	if(l==r) return pos;
    	if(k<=mid) ls[pos]=update(ls[pre],l,mid,k);
    	else rs[pos]=update(rs[pre],mid+1,r,k);
    	return pos;
    }
    // bool Existence(int x,int y,int l,int r,int Want)
    // {
    // 	if(l==r) return (cnt[y]-cnt[x])>=Want;
    // 	int mid=(l+r)>>1;
    // 	int LR=1;
    // 	if(cnt[ls[y]]-cnt[ls[x]]>cnt[rs[y]]-cnt[rs[x]]) LR=0;
    // 	else if(cnt[ls[y]]-cnt[ls[x]]<cnt[rs[y]]-cnt[rs[x]]) LR=2;
    // 	if(LR==0) return Existence(ls[x],ls[y],l,mid,Want);
    // 	if(LR==2) return Existence(rs[x],rs[y],mid+1,r,Want);
    // 	return Existence(ls[x],ls[y],l,mid,Want)|Existence(rs[x],rs[y],mid+1,r,Want);
    // }
    // int query(int x,int y,int l,int r,int k)
    // {
    // 	int mid=(l+r)>>1;
    // 	if(l==r) return b[l];
    // 	int dlt=cnt[ls[y]]-cnt[ls[x]];
    // 	if(dlt>=k) return query(ls[x],ls[y],l,mid,k);
    // 	else return query(rs[x],rs[y],mid+1,r,k-dlt);
    // }
    int query(int x,int y,int l,int r,int k)
    {
    	int mid=(l+r)>>1;
    	if(l==r) return l;
    	int L=cnt[ls[y]]-cnt[ls[x]],R=cnt[rs[y]]-cnt[rs[x]];
    	if(L>k) return query(ls[x],ls[y],l,mid,k);
    	if(R>k) return query(rs[x],rs[y],mid+1,r,k);
    	else return 0;
    }
    int main()
    {
    	int n,m; cin >> n >> m ;
    	for(int i=1;i<=n;i++) scanf("%d",&a[i])/* ,b[i]=a[i] */;
    	sort(b+1,b+n+1); /* int len=unique(b+1,b+n+1)-b-1; */
    	root[0]=build(1,n);
    	for(int i=1;i<=n;i++)
    	{
    		// int t=lower_bound(b+1,b+n+1,a[i])-b;
    		root[i]=update(root[i-1],1,n,a[i]);
    	}
    	for(int x,y,i=1;i<=m;i++)
    	{
    		scanf("%d%d",&x,&y);
    		// if(Existence(root[x-1],root[y],1,n,(y-x+1)/2+1)) printf("%d
    ",query(root[x-1],root[y],1,n,(y-x+1)/2+1));
    		// else printf("0
    ");
    		printf("%d
    ",query(root[x-1],root[y],1,n,(y-x+1)>>1));
    	}
    	return 0;
    }
    

    小结:主席树真强... ...

  • 相关阅读:
    Oracle安装错误ora-00922(zhuan)
    Context上下文对象(抄书的)
    我的oracle账号
    jquery总结(1)
    JS改变input的value值不触发onchange事件解决方案 (转)
    写表单验证等页面的总结
    表单验证模板2
    Session随便写的(抄书笔记)
    cookie随便写的一点笔记(抄书的)
    Oracle触发器修改数据时同步执行插入该条数据
  • 原文地址:https://www.cnblogs.com/ShuraK/p/9383690.html
Copyright © 2011-2022 走看看