• CF840D[Destiny] [主席树板子]


    模板题,提供两种思路。

    1.考虑它求得是 出现个数(>lfloor frac{r-l+1}{k} floor) 的最小值

    那么我们可以根据如果大于这个数那么你把这个区间数列排好序然后分段,分成 (k) 段,每次上下整都取,方便处理.webp

    因为 (kleq5) 所以上下整都取不会超过 (10) 个数字,依次查询,取个 (min) ,没了。

    2.考虑主席树本身的性质,他就是个权值线段树,直接放进来查询就完事了,左边的权值一定比右边的权值小,如果左边的出现个数大于 (lfloor frac{r-l+1}{k} floor) 那么很显然这边是有可能的,暴力找下试试看,如果不行的话,向右找,如果可以的话,这样依次找,直到找到了,一定是最小值,如果变成最大值的话,就从右边开始取

    // powered by c++11
    // by Isaunoya
    #include<bits/stdc++.h>
    #define rep(i , x , y) for(register int i = (x) ; i <= (y) ; ++ i)
    #define Rep(i , x , y) for(register int i = (x) ; i >= (y) ; -- i)
    using namespace std ;
    using db = double ;
    using ll = long long ;
    using uint = unsigned int ;
    #define int long long
    using pii = pair < int , int > ;
    #define ve vector
    #define Tp template
    #define all(v) v.begin() , v.end()
    #define sz(v) ((int)v.size())
    #define pb emplace_back
    #define fir first
    #define sec second
    // the cmin && cmax
    Tp < class T > void cmax(T & x , const T & y) { if(x < y) x = y ; }
    Tp < class T > void cmin(T & x , const T & y) { if(x > y) x = y ; }
    // sort , unique , reverse
    Tp < class T > void sort(ve < T > & v) { sort(all(v)) ; }
    Tp < class T > void unique(ve < T > & v) { sort(all(v)) ; v.erase(unique(all(v)) , v.end()) ; }
    Tp < class T > void reverse(ve < T > & v) { reverse(all(v)) ; }
    const int SZ = 0x191981 ;
    struct FILEIN {
    	~ FILEIN () {} char qwq[SZ] , * S = qwq , * T = qwq , ch ;
    	char GETC() { return (S == T) && (T = (S = qwq) + fread(qwq , 1 , SZ , stdin) , S == T) ? EOF : * S ++ ; }
    	FILEIN & operator >> (char & c) { while(isspace(c = GETC())) ; return * this ; }
    	FILEIN & operator >> (string & s) {
    		while(isspace(ch = GETC())) ; s = ch ;
    		while(! isspace(ch = GETC())) s += ch ; return * this ;
    	}
    	Tp < class T > void read(T & x) {
    		bool sign = 1 ; while((ch = GETC()) < 0x30) if(ch == 0x2d) sign = 0 ;
    		x = (ch ^ 0x30) ; while((ch = GETC()) > 0x2f) x = x * 0xa + (ch ^ 0x30) ;
    		x = sign ? x : -x ;
    	}
    	FILEIN & operator >> (int & x) { return read(x) , * this ; }
    	FILEIN & operator >> (signed & x) { return read(x) , * this ; }
    	FILEIN & operator >> (unsigned & x) { return read(x) , * this ; }
    } in ;
    struct FILEOUT { const static int LIMIT = 0x114514 ;
    	char quq[SZ] , ST[0x114] ; signed sz , O ;
    	~ FILEOUT () { sz = O = 0 ; }
    	void flush() { fwrite(quq , 1 , O , stdout) ; fflush(stdout) ; O = 0 ; }
    	FILEOUT & operator << (char c) { return quq[O ++] = c , * this ; }
    	FILEOUT & operator << (string str) {
    		if(O > LIMIT) flush() ; for(char c : str) quq[O ++] = c ; return * this ;
    	}
    	Tp < class T > void write(T x) {
    		if(O > LIMIT) flush() ; if(x < 0) { quq[O ++] = 0x2d ; x = -x ; }
    		do { ST[++ sz] = x % 0xa ^ 0x30 ; x /= 0xa ; } while(x) ;
    		while(sz) quq[O ++] = ST[sz --] ; return ;
    	}
    	FILEOUT & operator << (int x) { return write(x) , * this ; }
    	FILEOUT & operator << (signed x) { return write(x) , * this ; }
    	FILEOUT & operator << (unsigned x) { return write(x) , * this ; }
    } out ;
    
    int n , q ;
    const int maxn = 3e5 + 10 ;
    int a[maxn] , rt[maxn] ;
    int ls[maxn << 5] , rs[maxn << 5] , val[maxn << 5] ;
    int cnt = 0 ;
    void upd(int & p , int pre , int l , int r , int x) {
    	p = ++ cnt ;
    	val[p] = val[pre] + 1 ;
    	ls[p] = ls[pre] , rs[p] = rs[pre] ;
    	if(l == r) return ; 
    	int mid = l + r >> 1 ;
    	if(x <= mid) 
    		upd(ls[p] , ls[pre] , l , mid , x) ;
    	else 
    		upd(rs[p] , rs[pre] , mid + 1 , r , x) ;
    }
    //int kth(int a , int b , int l , int r , int k) {
    //	if(l == r) return l ;
    //	int x = val[ls[b]] - val[ls[a]] ;
    //	if(x <= k)
    //		return kth(ls[a] , ls[b] , l , mid , k) ;
    //	else 
    //		return kth(rs[a] , rs[b] , mid + 1 , r , k - x) ;
    //}
    //int count(int a , int b , int l , int r , int x) {
    //	if(l == r)
    //		return val[b] - val[a] ;
    //	int mid = l + r >> 1 ;
    //	if(x <= mid) 
    //		return count(ls[a] , ls[b] , l , mid , x) ;
    //	else 
    //		return count(rs[a] , rs[b] , mid + 1 , r , x) ;
    //}
    
    int qry(int a , int b , int l , int r , int k) {
    	if(l == r) return l ;
    	int x = val[ls[b]] - val[ls[a]] ;
    	int y = val[rs[b]] - val[rs[a]] ;
    	int mid = l + r >> 1 , ans = -1 ;
    	if(x > k) {
    		ans = qry(ls[a] , ls[b] , l , mid , k) ;
    	}
    	if(~ ans) return ans ;
    	if(y > k) {
    		ans = qry(rs[a] , rs[b] , mid + 1 , r , k) ;
    	}
    	return ans ;
    }
    signed main() {
    #ifdef _WIN64
    	freopen("testdata.in" , "r" , stdin) ;
    #else
    	ios_base :: sync_with_stdio(false) ;
    	cin.tie(nullptr) , cout.tie(nullptr) ;
    #endif
    // code begin.
    	in >> n >> q ;
    	rep(i , 1 , n) {
    		in >> a[i] ;
    	}
    	rep(i , 1 , n) {
    		upd(rt[i] , rt[i - 1] , 1 , n , a[i]) ;
    	}
    	while(q --) {
    		int l , r , k ;
    		in >> l >> r >> k ;
    		k = (r - l + 1) / k ;
    		out << qry(rt[-- l] , rt[r] , 1 , n , k) << '
    ' ;
    	}
    	return out.flush() , 0 ;
    // code end.
    }
    
  • 相关阅读:
    python3.7安装pygame
    Jmeter定时器
    弱网测试
    面试心得123
    如何保证测试项目的质量
    LeetCode448-数组中消失的数字
    LeetCode-两数相加
    JVM-Class文件的结构
    leetcode-222完全二叉树的节点个数
    Java虚拟机常用的性能监控工具
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12267337.html
Copyright © 2020-2023  润新知