zoukankan      html  css  js  c++  java
  • P3567 [POI2014]KUR-Couriers

    LuoguP3567 [POI2014]KUR-Couriers

    菜死了,竟然没看出来这是一道主席树的模板题.还自己瞎YY了写奇技淫巧。
    首先([l,r])这个区间的主席树我们是很好求的。
    如果一个数出现的次数严格大于((r - l + 1) / 2)
    那么,第((r - l + 1) /2)大的数肯定是他,
    但是,怎么判断第((r - l + 1)/2)大的数到底出现没出现更多次,好像没有思路。
    但是,在递归查询第(k)大的时候,查询的排名不随区间改变而改变就好了
    煮个栗子
    普通的主席树如果左儿子(默认使用当前区间的主席树)有(k - 1)个数
    我们将问题转化为查询右儿子第一大
    但是这道题去查询右儿子第(k)大,如果右儿子也不足(k),说明没有数出现了((r - l + 1) /2)

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cctype>
    using namespace std;
    const int N = 5e5 + 3;
    struct node{
    	int sum;
    	int lc,rc;	
    }a[N * 30];
    int v[N],b[N],rt[N];
    int n,m,t;
    inline int read(){
    	int v = 0,c = 1;char ch = getchar();
    	while(!isdigit(ch)){
    		if(ch == '-') c = -1;
    		ch = getchar();	
    	}
    	while(isdigit(ch)){
    		v = v * 10 + ch - 48;
    		ch = getchar();	
    	}
    	return v * c;	
    }
    inline void ins(int &u,int l,int r,int x){
    	a[++t] = a[u];
    	u = t;
    	if(l == r){
    		a[u].sum ++;
    		return ;
    	}
    	int mid = (l + r) >> 1;
    	if(x <= mid) ins(a[u].lc,l,mid,x);
    	else ins(a[u].rc,mid + 1,r,x);
    	a[u].sum = a[a[u].lc].sum + a[a[u].rc].sum;
    }
    inline int query(int u1,int u2,int l,int r,int x){
    	if(l == r) return l;
    	int s1 = a[a[u2].lc].sum - a[a[u1].lc].sum,s2 = a[a[u2].rc].sum - a[a[u1].rc].sum;
    //	printf("%d %d
    ",s1,s2);
    	int mid = (l + r) >> 1;
    	if(s1 > x) return query(a[u1].lc,a[u2].lc,l,mid,x);
    	else if(s2 > x) return query(a[u1].rc,a[u2].rc,mid + 1,r,x);
    	else return 0;	
    }
    int main(){
    	n = read(),m = read();
    	for(int i = 1;i <= n;++i) v[i] = b[i] = read();
    	sort(b + 1,b + n + 1);
    	b[0] = unique(b + 1,b + n + 1) - b - 1;
    	for(int i = 1;i <= n;++i){
    		rt[i] = rt[i - 1];
    		v[i] = lower_bound(b + 1,b + b[0] + 1,v[i]) - b;
    		ins(rt[i],1,b[0],v[i]);
    	}
    	while(m--){
    		int l = read(),r = read();
    		int k = (r - l + 1) / 2;
    		int ans = query(rt[l - 1],rt[r],1,b[0],k);
    		printf("%d
    ",ans == 0 ? ans : b[ans]);	
    	}
    	return 0;	
    }
    
  • 相关阅读:
    从零搭建一个IdentityServer——资源与访问控制
    职 工 养 老 保 险 转 移—陕西省外转入
    EurekaUser-Redis
    EurekaUser-返回类型和全局异常
    C# 入门实战系列文章
    Python入门实战系列文章
    Python基础之Scrapy简介
    Python办公自动化之文件合并
    Python基础之shutil及zipfile模块
    Python基础之os模块简介
  • 原文地址:https://www.cnblogs.com/wyxdrqc/p/10641271.html
Copyright © 2011-2022 走看看