1 1 有關long long 運算的建議 打完代碼一定要考慮long long問題,該開的一定要開! 方案1 取模三件套 int add(int a,int b){ return (a+b)%MOD; } int mul(int a,int b){ return 1LL*a*b%MOD; } int sub(int a,int b){ return (a-b+MOD)%MOD; } 快速乘 LL mul(LL x,LL y,LL MOD){ LL res=(x*y-(LL)((double)x*y/MOD+0.1)*MOD)%MOD; if(res<0)res+=MOD; return res; } 方案2 #define int_ long long 很浪費空間\時間,不建議… 2 空間消耗問題 3 ??臻g問題 關于爆棧: 兩種情況,遞歸層數(shù)太多(RE),遞歸時傳了一個數(shù)組[還包括STL(set,bitset,map…)](RE或MLE) 解決方案: 4 重載運算符的運用 bool operator <(const state &b)const{//STL習慣用<符號 return step>b.step; } 5 STL 用STL的時候要小心邊界,很容易崩潰 5.1 set/multiset s.lower_bound(val)——尋找第一個大于等于val valval的s ss中的元素(被坑過兩次,一次是某次Atcoder 還有一次是NOIP 開車旅行) s.upper_bound(val)——set用這東西好像沒用 s.find(val)——找到當前=val =val=val的迭代器。 s.erase(*it)——一定注意里面是迭代器,如果要刪val的話需要先s.find(val)。 s.count(val)——multiset才用的著,元素中=val =val=val的個數(shù)。 5.2 string C++的string真的很好用…雖然很慢…但在模擬題中是很實用的(CSP能用)。 s.substr(l,len)取以l開始的后面len個字符,len如果省去的話就默認直到結尾。 s.substr(l,len)刪除l開始的后面len個字符,len如果省去的話就默認直到結尾,與上一個(大概是)反函數(shù)。 s.find(string)找string是否存在,存在返回第一個出現(xiàn)的第一個字符所在位置,否則返回string::npos。 5.3 vector 不建議用…因為有些操作是可以被卡到O(n) O(n)O(n)的。 G.resize(siz)預留siz的空間,[siz,end)的全部刪掉。 5.4 bitset S.set(idx,val)將idx位置置為val,val省略是默認為1。 S.count()數(shù)bitset中1的個數(shù)。 S.size()bitset的大小。 S.test(idx)查詢當前下標是否為1。 S.any()查詢bitset中是否有1。 S.all()查詢bitset中是否全部都是1。 eg.biset Floyd 閉包 for(register int i=1;i<=n;i++)//相當于之前的k,要放在外面 for(register int j=1;j<=n;j++) if(d[j][i])d[j]|=d[i]; 6 CE/文件操作相關 眾所周知CE和MLE是OI中最可怕的兩種錯誤 注意一些變量名在NOI Linux下是禁用的! 最可怕的就是x1,y1這種東西…還有一些常見的英文單詞,因此拼寫的時候盡量在英文單詞中刪幾個字母(不過像slove這樣的單詞就沒必要了,今年我還是別用process了)。 #include<cstdio> #include<iostream> 頭文件一定要加!雖然可能能夠通過編譯! 還有要注意莫名其妙的多余隱藏字符(當然這個比較玄學)。 freopen('road.in','r',stdin); freopen('road.out','w',stdout); 必須一個單詞不多不少!空格也不行!! 7 對拍相關 考試的時候肯定是首先測大樣例,輸出多的時候要用fc A.out B.out。 然后自己出幾組小數(shù)據(jù),如果行的話構造一些大數(shù)據(jù)。 如果考試時間十分充足,一定要進行對拍 以下是對拍的程序: #include<iostream> #include<windows.h> using namespace std; int main() { int testdata=100; while(1) { testdata--; system('makedata_plus.exe %random% > data.in');//%random%是隨機參數(shù),可加可不加 system('cheat.exe < data.in > cheat.out');//< 就是讀入 > 就是輸出 system('bf.exe < data.in > bf.out'); if(system('fc cheat.out bf.out'))break; } if(testdata==0) cout<<'no error'<<endl; else cout<<'error'<<endl; system('pause'); return 0; } 隨機生成數(shù)據(jù)(僅供參考): #include <bits/stdc++.h> #define LL long long #define MAXN 200000 #define RANGE 100000 using namespace std; stringstream ss; int n,fa[MAXN+5],p[MAXN+5]; int get_num(){ return 1LL*rand()*rand()%(RANGE*2)-RANGE; } int xfind(int x){ return (fa[x]==x)?x:fa[x]=xfind(fa[x]); } int main(int argc, char *argv[]) { int i=10,kd=0; if(argc){ ss.clear(); ss<<argv[1]; ss>>i; //kd=(i/20)%2; i%=20; } int data[21][3]={ {1,1,1}, {10,2,6}, {17,4,10}, {35,5,8}, {70,3,14}, {200,5,18}, {200,6,37}, {500,20,868}, {500,20,742}, {1000,100,998}, {1000,100,997}, {1000,99,996}, {1000,99,995}, {1000,100,994}, {1000,100,993}, {1000,99,992}, {1000,99,991}, {1000,100,990}, {1000,100,989}, {1000,99,988}, {1000,99,987}}; static char buf[1000]; srand(time(NULL)); n=data[i][0]; printf('%d\n',n); p[1]=1; for(int j=2;j<=n;j++) fa[j]=1LL*rand()*rand()%(j-1)+1,p[j]=j; for(int j=1;j<=n;j++) printf('%d ',get_num()); printf('\n'); for(int j=1;j<=n;j++) printf('%d ',get_num()); printf('\n'); if(kd){ for(int j=2;j<=n;j++)printf('%d %d\n',j-1,j); return 0; }else{ random_shuffle(p+1,p+n+1); for(int j=2;j<=n;j++) printf('%d %d\n',p[fa[j]],p[j]); } return 0; } 8 一些小細節(jié) 倍增:注意先枚舉k再枚舉i。 線段樹如果有負下標應將mid設為(l+r)>>1,不能用(l+r)/2,因為C++除法向取整。 多關鍵字更新答案一定要注意順序。 example: if(maxh==h&&mxa>a)mxa=a; if(maxh<h)maxh=h,mxa=a;//不能夠交換順序 4.以后檢查代碼的時重點還是應該在檢查是否手殘上:)因為我經常手殘:) 5.多組數(shù)據(jù)一定要清空??!清空?。∏蹇眨?! 數(shù)據(jù)千萬條,清空第一條。 多測不清空,爆零兩行淚。 9 考試策略相關 拿到題目首先看第一頁的時空限制以及文件及題目名(感受出題人的毒瘤)。 然后看題面,最好把三道題目都讀完,預估一下總體難度如何,最好心里排個序,但在NOIP這種情況還是很少見(除了NOIP2016 day1)。 然后開始做題,建議從子任務一步一步做著走,這在NOIP中是十分有用的,因為出題人會給你很多提示,但平時的考試就很難說了… 通過的測試點可以在上面打個標記,可以讓你有一種成就感。 選擇打正解還是打暴力一直是我很頭疼的事情。按理來說NOIP的部分分大多是思維型的,不會浪費太多時間。 做完一道難題可以去上上廁所,實測很實用。 ———————————————— 本文來源:https://blog.csdn.net/qq_34940287/article/details/102066630 |
|