Little Elephant and Array 線段樹

來源:互聯網
上載者:User

       
題目

        前幾篇文章中出現了“靠”等字眼,一次偶然的機會百度到了一篇轉載自我的文章,轉載者將問中的包含“情緒”的語句全部刪掉了,我這才注意到,最近我變得很容易情緒不好!!我錯了,我想起了高中一老師說的“心靜如水,激情似火”!看來我需要修鍊的東西還很多啊……

        題目大意:給定10^5的一個數組,(10^5次)查詢給定區間中出現次數和這個數的值相同的數的個數

例如:

7 23 1 2 2 3 3 71 73 4

7個數2個詢問1-7中1出現1次、2出現2次、3出現3次,所以答案為3。3-4中只有2出現2次,所以答案為1

代碼寫的有點挫,因為調試了好久。首先給定數組後,可以成為答案的數字不會超過500個(1+2*2+3*3+……500*500 > 10^5)

其次,離線處理也是比較常見的!由於x出現恰好是x次,所以需要將向左第x個標記為1,向左第x+1個就要標記為-1,其餘標記為0,這樣就可以有效查詢區間中恰好出現x次的數字個數(區間求和)

/**離線線段樹問題*/#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#include <map>#include <queue>using namespace std;#define N 100010int ai[N],_ai[N],re[N];struct note{    int l,r,index;}query[N];bool q_cmp(const note a,const note b){    return a.r < b.r ||(a.r == b.r && a.l < b.l);}int num[N];///線段樹#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define fmid int m = (l+r)>>1;int sum[N*4];void init(){    memset(sum,0,sizeof(sum));}void push_up(int rt){    sum[rt] = sum[rt<<1] + sum[rt<<1|1];}int f_query(int L,int R,int l,int r,int rt){    if(L <= l && r <= R)    {        return sum[rt];    }    fmid;    int re = 0;    if(L <= m) re += f_query(L,R,lson);    if(m < R) re += f_query(L,R,rson);    return re;}void update(int pos,int val,int l,int r,int rt){    if(pos == 0) return;    if(l == r)    {        sum[rt] = val;        return;    }    fmid;    if(pos <= m) update(pos,val,lson);    else update(pos,val,rson);    push_up(rt);}///PPPPPPPPPPPPPPPPPPPPPvoid _update(int pos,int val,int l,int r,int rt){    //cout << pos << " " << val << "\n";    update(pos,val,l,r,rt);}int main(){    int n,m;    while(cin >> n >> m)    {        for(int i = 1;i <= n;i++) scanf("%d",&ai[i]);        for(int i = 0;i < m;i++) scanf("%d%d",&query[i].l,&query[i].r);        for(int i = 0;i < m;i++) query[i].index = i;        sort(query,query+m,q_cmp);        for(int i = 1;i <= n;i++) _ai[i] = ai[i];        sort(_ai+1,_ai+n+1);        memset(num,0,sizeof(num));        num[1] = 1;        int kk = 1;        for(int i = 2;i <= n;i++)        {            if(_ai[i] == _ai[i-1]) num[kk]++;            else            {                _ai[++kk] = _ai[i];                num[kk] = 1;            }        }        int k = 1;        for(int i = 1;i <= kk;i++)        {            if(num[i] >= _ai[i]) _ai[k++] = _ai[i];        }        map <int ,int> mymap;        kk = 1;        for(int i = 1;i < k;i++)        {            mymap[ _ai[i] ] = kk++;        }        //for(int i = 1;i < k;i++) cout << _ai[i] << " ";cout << kk << " ppp\n";        kk = 0;        init();        queue < int > my_queue[500];        int t_pos[500];        memset(t_pos,0,sizeof(t_pos));        for(int i = 1;i <= n;i++)        {            int t = mymap[ ai[i] ];            if(t != 0)            {                my_queue[t].push(i);                int size = my_queue[t].size() ;                if(size == ai[i]) _update(my_queue[t].front(),1,1,n,1);//第一出出現ai[i]次                if(size == ai[i]+1)                {                    _update(t_pos[t],0,1,n,1);//注意將-1左側的改為0                    t_pos[t] = my_queue[t].front();//記錄標記為-1的點,已備以後改為0                    _update(my_queue[t].front(),-1,1,n,1);//修改為-1                    my_queue[t].pop();                    _update(my_queue[t].front(),1,1,n,1);//將左側底ai[i]個ao[i]標記為1                }            }            while(kk < m && query[kk].r == i)            {                re[query[kk].index] = f_query(query[kk].l,query[kk].r,1,n,1);//查詢該區間的值得情況                kk++;            }        }        for(int i = 0;i < m;i++) cout << re[i] << "\n";    }    return 0;}

奇怪,這個代碼居然又wa在了第33組範例,已近過了的題目原來還是可以再錯的啊!!!囧,我抽空看看怎麼回事!!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.