[STL]hdu5233

題意:
給出一組數據n個數,m個詢問q,問最近的q的輸入下標是多少?

分析:
首先數據量比較大100000,查詢的話肯定要用些技巧,剛開始想的是二分查詢,用set,可是不知道set裏放數據結構struct如何按照關鍵字lower_bound()。後來看了官方題解,先把數據離散話,然後利用set[]來存儲下標。那麼輸出的時候就直接輸出begin,刪除也可以erase().
這裏有個trick,剛開始用的vector q[],然後T。。。後來換set就A了,原來vector<>的push_back()是O(n)的,set的inset是O(logn).

這裏簡單查一下vector push_back的知識,當每次push_back的時候vector法先空間不夠的時候就會copy元素,然後擴大空間,vector 的 push_back 在發現空間不足時自動將空間以 2 的指數增長:0 -> 1 -> 2 -> 4 -> 8 -> 16 -> 32 …

引用:
http://blog.csdn.net/tyzhaoqi2004/article/details/6882660

vector管理內存的方式是內存不夠用時,就分配capacity大小的內存,每次重新分配內存,都要copy之前放入的元素,capacity爲已經分配的內存。

例如:push_back n個int元素,n爲2的冪次加1

元素序號 copy元素 capacity

1 1 1

2 2 2

3 3 4

4 1 4

5 5 8

.。。。

n n 2n

歸納得到copy元素次數字和爲

1+2+4+8.。。+(n-1)/2+(n-1)+n

前面部分爲一個等比數列,求和爲(n-1)/2,最後數列求和爲3n-1/3,時間複雜度爲O(n)。

所以在不指定reverse的時候,vector push_back n個元素的時間複雜度爲O(n)。

對於set:
set::find和set::insert消耗時間級別都爲logN.


可是試了一下預先分配vector的空間大小,還是T。。。

好吧,來看一下vector的erase函數

    template<typename _Tp,_Alloc>typename vector<_Tp,_Alloc>::iterator  
    vector<_Tp,_Alloc>::erase(iterator __postion) {  
        if (__postion + 1 != end())  
            std::copy(__postion + 1, end(), __postion);  
        --this->_M_impl._M_finish;  
        this->_M_impl.destroy(this->_M_impl._M_finish);  
        return __postion;  
    }  

它是O(n)是把刪除數據後面的數據copy到前面。copy是把刪除元素位置後面元素向前移位, 然後 –finish把end位向前移動, 這2句都好理解保持內存連續把刪除的空位補上同時把隊尾往前挪。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#define read freopen("q.in","r",stdin)
#define LL long long
#define maxn 100005
using namespace std;
set<int>  mp[maxn];
map<int,int> c;
//http://www.2cto.com/kf/201108/100912.html
//http://blog.csdn.net/tyzhaoqi2004/article/details/6882660
int main()
{
    //read;
   int n,m;
   while(scanf("%d%d",&n,&m)!=EOF)
   {
       int i,j,q,x,t=0;
       for(i=1;i<=n;i++)
        mp[i].clear();
        c.clear();
       for(i=0;i<n;i++)
       {
          scanf("%d",&x);
          if(!c[x])c[x]=++t;
          mp[c[x]].insert(i+1);

         // cout<<c[x]<<" ";
       }
       //for(i=1;i<=t;i++)cout<<c[i]<<" ";
    //   cout<<endl;
       for(i=0;i<m;i++)
       {
          scanf("%d",&q);
          if(mp[c[q]].size()==0)
          {
             printf("-1\n");
          }
          else
          {
            //  cout<<mp[q].size()<<" %% "<<endl;
             printf("%d\n",*(mp[c[q]].begin()));
             mp[c[q]].erase(mp[c[q]].begin());
            // cout<<mp[q].size()<<" %% "<<endl;
          }
       }

    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章