zoukankan      html  css  js  c++  java
  • Codeforces 1261B2 Optimal Subsequences (Hard Version)(树状数组)

    思路:

    1.听说这题可以用主席树orz,本菜鸟学了一天主席树,发现主席树可以很方便的求任意区间的第k小/大,但是这题区间里的数是动态的,然后就束手无策了QAQ;
    2.这题先把数据都保存下来,然后离线求每个询问;对于每个数,我们用pair存储,值大的排在前面,值相同的序号小的排在前面(用贪心思想迎合题意);对于每个查询,我们按它的k分类存储,存在一个vector<pair<int,int>> q[]里面,每个pair存储{该询问的序号,该询问是求第pos小}
    3.然后使用BIT来降低复杂度,每轮都新增一个点进去,然后去完成该长度的查询(这就是为什么用k将查询分类;由于BITsum是按序号递增的,我们可以二分查找自己需要的位置,查询到位置的下标后就可以得到这个位置的值了;

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int,int> P;
    #define fi first
    #define sc second
    #define pb(a) push_back(a)
    #define mp(a,b) make_pair(a,b)
    #define rp(i,n) for(int i=0;i<n;i++)
    #define rpn(i,n) for(int i=1;i<=n;i++)
    template <class T>
    inline bool read(T &ret){
    	char c; int sgn;
    	if(c=getchar(),c==EOF) return 0; //EOF
    	while(c!='-'&&(c<'0'||c>'9')) c=getchar();
    	sgn=(c=='-')?-1:1;
    	ret=(c=='-')?0:(c-'0');
    	while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
    	ret*=sgn; return 1;
    }
    inline void out(int x){
    	if(x<0) {putchar('-'); x*=-1;}
    	if(x>9) out(x/10); putchar(x%10+'0');
    }
    int n;
    const int MAX_N=2e5+99;
    P a[MAX_N];    //a[] 序号/值
    vector<P> q[MAX_N];      // q[] 序号/pos 
    int val[MAX_N],rst[MAX_N];
    int bit[MAX_N];
    int sum(int i){
    	int s=0;
    	while(i>0) s+=bit[i],i-=i&-i;
    	return s;
    }
    void add(int i){
    	while(i<=n) bit[i]++,i+=i&-i;
    }
    int bin_search(int index){ 
    	int l=1,r=n,ans;
    	while(l<=r){
    		int mid=(l+r)>>1;
    		if(sum(mid)>=index) r=mid-1,ans=mid;
    		else l=mid+1;
    	}
    	return val[ans];
    }
    bool cmp(const P& a,const P& b){
    	return a.sc==b.sc?a.fi<b.fi:a.sc>b.sc;
    }
    int main(){
    	read(n);
    	rpn(i,n) a[i].fi=i,read(a[i].sc),val[i]=a[i].sc;
    	sort(a+1,a+n+1,cmp);
    	int m; read(m);
    	rpn(i,m){
    		int k,pos; read(k); read(pos);
    		q[k].pb(mp(i,pos));
    	}
    	rpn(i,n){
    		add(a[i].fi);
    		for(auto x:q[i]) rst[x.fi]=bin_search(x.sc);
    	}
    	rpn(i,m) out(rst[i]),putchar('
    ');
    	return 0;
    }
    
  • 相关阅读:
    第二次作业循环语句
    c语言01次作业分支,顺序结构
    PAT 1027. Colors in Mars
    PAT 1026 Table Tennis
    PAT 1035 Password
    PAT 1038. Recover the Smallest Number
    PAT 1028 List Sorting (25)
    PAT 1041 Be Unique (20)
    PAT 1025 PAT Ranking
    1037. Magic Coupon
  • 原文地址:https://www.cnblogs.com/yuhan-blog/p/12308816.html
Copyright © 2011-2022 走看看