開vector時要注意記憶體容易炸
最好的辦法就是在開vector之後,對他進行一步操作
vector<int> a; a.resize(n);
n就是你要開的陣列的大小,此時陣列裡已經插入了n個零,佔記憶體空間也只有n個int
還有另外一種方法
vector<int> a; a.reserve(n);
這個就是關於記憶體的事了,此時我們已經將這個動態陣列的大小固定了,就是說,它已經變成了一個普通的陣列,只不過可以開的大一些
但是,這個時候vector內的下標是不可以直接呼叫的,因為這裡只是控制了空間大小,而每一個下標內是沒有值的
這裡有兩種辦法,一個就是上面的resize()還有就是暴力插0
vector<int> a; for(int i=1;i<n;i++) a.push_back(0);
不過這樣寫應該比第一種要慢一些
第一種的時間及記憶體
#include<bits/stdc++.h> using namespace std; #define re register int #define ll long long ll n; vector<int> a; int b[100000000]; signed main(){ n=5e8; cout<<n/1024/1024<<endl; a.reserve(n+10); a.resize(n); //for(re i=1;i<=n;i++)a.push_back(0); cout<<a.max_size()<<endl<<a.capacity()<<endl; } 476 1073741823 500000010 real 0m1.079s user 0m0.916s sys 0m0.160s
第二種的時間及記憶體
#include<bits/stdc++.h> using namespace std; #define re register int #define ll long long ll n; vector<int> a; int b[100000000]; signed main(){ n=5e8; cout<<n/1024/1024<<endl; a.reserve(n+10); //a.resize(n); for(re i=1;i<=n;i++)a.push_back(0); cout<<a.max_size()<<endl<<a.capacity()<<endl; } 476 1073741823 500000010 real 0m6.116s user 0m6.000s sys 0m0.116s
可以清晰的看到下面那個炸了
為什麼要說這些呢
因為,vector在內部開空間的時候,是在2的指數級上開的空間
就是如果空間不夠了,他會直接把你用的空間*2
然後直接炸掉你的空間,然後導致你暴零
所以我們在利用vector做題時,最好限制一下它的空間,可以讓記憶體保持在一個可控的範圍內
還有時間問題,注意resize比直接插入快。。。。
我也不知道為什麼我的電腦之讓我把陣列開到5e8
而別人的電腦都可以開到2305843009213693951
害noi_linux欺負人