• POJ2104 K-th Number (平方分割 + 二分)


     
    题目链接:传送门
     

     
    题意:输入n个数,然后进行m次操作,每次操作输入三个数l,r,k,输出在[l,r]区间第k小的数

    解题思路:这道题做法倒是挺多的,平方分割可以做,归并树,划分树,主席树都能做,但是本片博客主要讲解一下平方分割的做法(比较简单),我们把n个数分为n/1000个桶,然后我们维护每个桶即可,我们通过预处理把每个桶的元素进行排序处理,然后我们二分查找第k小的数字,在[l,r]这个区间比第第k小的数字肯定只有k-1个,比第k大的数字只有(r-l+1)-k个,我们会发现我们查询的区间无非就两种情况,第一种,就是查询区间完全被包含在区间内,第二种就是所在的桶不完全包含区间内的元素,需要我们逐步处理,时间复杂度为(O(nlogn+msqrt{n}log^1.5n))

    Code:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    using namespace std;
    
    const int B = 1000, N = 100005;
    int n,m;
    int a[N],b[N];
    vector<int> ton[N/B+1];
    
    int main()
    {
    	int t;
    	scanf("%d%d",&n,&m);
    	for(int i = 0;i < n; ++i) {
    		scanf("%d",&a[i]);
    		ton[i/B].push_back(a[i]);
    		b[i] = a[i];
    	}
    	sort(b,b+n);
    	for(int i = 0,len = n/B;i < len; ++i) {
    		sort(ton[i].begin(),ton[i].end());//对每一个桶进行预处理
    	}
    	int l,r,k;
    	while(m--) {
    		scanf("%d%d%d",&l,&r,&k);
    		l--;
    		int lb = -1, rb = n;
    		while(lb + 1 < rb) {//二分查找x
    			int mid = (lb + rb) >> 1;
    			int x = b[mid];
    			int tl = l,tr = r, c = 0;
    			while(tl < tr && tl % B != 0) if(a[tl++] <= x) c++;//左边不在同一个桶里面的
    			while(tl < tr && tr % B != 0) if(a[--tr] <= x) c++;//右边不在同一个桶里面的
    			while(tl < tr) {
    				int bb = tl /B;
    				c += upper_bound(ton[bb].begin(),ton[bb].end(),x) - ton[bb].begin();
    				tl += B;
    			}
    			if(c >= k)
    				rb = mid;
    			else
    				lb = mid;
    		}
    		printf("%d
    ",b[rb]);
    	}
    
    	return 0;
    }
    

    PS:同样的题目POJ能AC,在HDU会T,原因因该是HDU的数据和POJ的不太同,但是HDU的可以通过其他三种方法做出,学后再出关于归并树,划分树,主席树的做法

  • 相关阅读:
    C#中的String.Length获取中文字符串长度出错
    PHP+Jquery+Ajax实现checkbox多选删除功能
    WIndows下AppAche服务中调试php页面出现警告:Call to undefined function mysql_connect()
    简洁的SQL一条语句更新从属账号
    算法导论数论一般离散对数问题
    Poj 2115
    算法导论数论计算x^2=1(mod n) 在区间[1,n1]的解
    算法导论数论RSA公钥加密系统
    算法导论数论中国余数定理
    Poj 2891 中国剩余定理 非互素
  • 原文地址:https://www.cnblogs.com/Mangata/p/14304170.html
Copyright © 2020-2023  润新知