C++ STL vector 容器数组与双重容器的效率问题

南城边 2013-08-13 07:34:27
在写 POJ3321 Apple Tree 的时候,保存一个图(树)的边,我用容器数组(vector<int> E[MAXN])来保存提交会超时(2000ms的时限),但是用双重容器vector< vector<int> > E(MAXN)来保存的话提交1000ms过了。为什么这里容器数组的效率比双重容器慢这么多?按照我的理解,容器是以链表形式保存数据的,通过下标访问容器元素时需要通过线性扫描定位,而通过下标访问数组时不过是需要增加指针的偏移量而以。数组形式应该比容器形式快得多才是。。。请教各位大神此处何解。。。
...全文
426 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
南城边 2013-08-14
  • 打赏
  • 举报
回复
http://paste.ubuntu.com/5983691/ 第一次发帖不会贴代码--!贴上去缩进都没了。。。贴paste里面了。。。劳烦大神了。。。
南城边 2013-08-14
  • 打赏
  • 举报
回复
#include<vector> #include<cstdio> #include<cstring> using namespace std; #define LSON(N) ((N)<<1 ) #define RSON(N) ((N)<<1|1) #define MID(L,R) (((L)+(R))>>1) const int MAXN=100005; int N,M,CntFork,TreeL[MAXN],TreeR[MAXN],SegmTree[MAXN<<2]; bool ExisApple[MAXN]; //不可改为vector<int> E[MAXN] vector< vector<int> > E(MAXN); void DFS(int Index) { TreeL[Index]=CntFork; for(int i=0;i<E[Index].size();++i) { ++CntFork; DFS(E[Index][i]); } TreeR[Index]=CntFork; } void Insert(int InsID,int InsVal,int L,int R,int N) { SegmTree[N]+=InsVal; if(L!=R) { int M=MID(L,R); if(InsID<=M) { Insert(InsID,InsVal,L,M,LSON(N)); } else { Insert(InsID,InsVal,M+1,R,RSON(N)); } } } int Query(int QueL,int QueR,int L,int R,int N) { if(QueR<L||R<QueL) { return 0; } if(QueL<=L&&R<=QueR) { return SegmTree[N]; } int M=MID(L,R); return Query(QueL,QueR,L,M,LSON(N))+Query(QueL,QueR,M+1,R,RSON(N)); } bool InitData() { memset(SegmTree,0,sizeof(SegmTree)); for(int i=1;i<=N;++i) { ExisApple[i]=1; Insert(i,1,1,N,1); E[i].clear(); } return true; } int main() { while(scanf("%d",&N)==1) { InitData(); for(int i=1;i<N;++i) { int u,v; scanf("%d%d",&u,&v); E[u].push_back(v); } CntFork=1; DFS(1); scanf("%d",&M); while(M--) { int x; char ch; scanf("%*c%c%d",&ch,&x); if(ch=='Q') { printf("%d\n",Query(TreeL[x],TreeR[x],1,N,1)); } else { ExisApple[x]^=1; Insert(TreeL[x],(ExisApple[x]?1:-1),1,N,1); } } } return 0; }
FancyMouse 2013-08-14
  • 打赏
  • 举报
回复
写没写扯只能看代码
南城边 2013-08-14
  • 打赏
  • 举报
回复
>因为你其他地方写扯了 我在代码中对vector的操作是首先对每个E[i]调用clear()清空,然后使用push_back()加入元素,再通过E[i][j]的形式访问了所有加入的元素,当然循环访问的时候还调用了E[i].size(),没有用什么奇葩的函数。。。 >容器是以链表形式保存数据的 我知道vector是动态array,既然它是动态的,在动态扩张数组时它就不可避免的用到指针来保存新的数据域,那么在访问的时候它就只能是扫描访问了。。。撇开这些不说,无论如何它也不应该比数组形式访问来得快吧?
南城边 2013-08-14
  • 打赏
  • 举报
回复
额--!是肯定会挂。。。做的时候思路也不是很清晰没注意,谢谢指出来。。。正确的做法应该是弄成双向边,DFS访问的时候判下重复就可以了吧。。。
FancyMouse 2013-08-14
  • 打赏
  • 举报
回复
我奇怪这代码为啥能过。输入的边如果uv换个顺序你这代码岂不是就会挂?
FancyMouse 2013-08-14
  • 打赏
  • 举报
回复
因为你其他地方写扯了 >容器是以链表形式保存数据的 vector就是个动态array。链表是list。vector不会有链表行为的。
南城边 2013-08-14
  • 打赏
  • 举报
回复
刚刚看了下vector倍增的含义,“容器是以链表形式保存数据的”这句话说错了(知识浅陋唉没办法)。。。但即使在vector的倍增机制下其空间是连续的,这样访问速度最多只能和数组相同而不能远大于吧?
chen_tr 2013-08-14
  • 打赏
  • 举报
回复
vector是倍增的,当空间不够时,会进行倍增操作

33,006

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧