acdreamoj1108(The kth number)

來源:互聯網
上載者:User

標籤:style   class   blog   code   http   com   

題目連結:http://acdream.info/problem?pid=1108

題意:n個數的數列,m次查詢某個區間出現次數第k多的數出現的次數。n,m<=100000


解法:這個因為是離線的所以可以先統一處理,然後再輸出。可以維護一個left和right指標,pre,pre[i]表示此時區間內出現次數大於等於i的數的種類。為了減少複雜度,關鍵是left和right的移動方式,即查詢區間如何排序,如果緊靠區間左端點排序,那麼右端點每次一定最大回是n,如果按照右端點排序,左端點每次一定最大是n。這裡有個很好的處理辦法,就是模糊排序,先左端點非嚴格排序,即除以sqrt(n)再排序,這樣複雜度最大是n*sqrt(n)


代碼:

/******************************************************* @author:xiefubao*******************************************************/#pragma comment(linker, "/STACK:102400000,102400000")#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <queue>#include <vector>#include <algorithm>#include <cmath>#include <map>#include <set>#include <stack>#include <string.h>//freopen ("in.txt" , "r" , stdin);using namespace std;#define eps 1e-8#define zero(_) (abs(_)<=eps)const double pi=acos(-1.0);typedef long long LL;const int Max=100010;const int INF=1e9+7;int num[Max];int help[Max];int r[Max];int l[Max];int k[Max];int pre[Max];int cnt[Max];int tool;bool cmp(int i,int j){    if(l[i]/tool==l[j]/tool&&r[i]!=r[j])        return r[i]<r[j];    return l[i]<l[j];}int ans[Max];int n,m;int findans(int t){    int l=1,r=n;    while(l<=r)    {        int middle=(l+r)/2;        if(pre[middle]>=t)        l=middle+1;        else            r=middle-1;    }    return l-1;}int main(){    int t;    cin>>t;    while(t--)    {        scanf("%d%d",&n,&m);        tool=sqrt(n);        for(int i=0; i<n; i++)            scanf("%d",num+i),help[i]=i;        for(int i=0; i<m; i++)            scanf("%d%d%d",l+i,r+i,k+i),l[i]--,r[i]--;        sort(help,help+m,cmp);        memset(cnt,0,sizeof cnt);        memset(pre,0,sizeof pre);        int left=0,right=-1;        for(int i=0;i<m;i++)        {           int L=l[help[i]],R=r[help[i]];           while(left<L){ pre[cnt[num[left++]]--]--;}           while(L<left){ pre[++cnt[num[--left]]]++;}           while(right<R){ pre[++cnt[num[++right]]]++;}           while(R<right){ pre[cnt[num[right--]]--]--;}           ans[help[i]]=findans(k[help[i]]);        }        for(int i=0;i<m;i++)            printf("%d\n",ans[i]);    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.