题目不附了,是一个单纯的ST模型,但是考验各种常数优化。
最大的优化是对于同颜色的客栈来说,如果1号和2号成功配对了,那么1和3,1和4都可以成功配对,那么只要找到一对成功配对的,我们就直接加上剩下的对数就好了。
代码之中使用了一些特殊的存储方式做了点查询枚举的优化,可能有点难看……我找个时间敲一个比较易懂的代码,在那之前就麻烦客官看看这个丑的要死的代码了OYZ
1 #include <algorithm> 2 #include <iostream> 3 #include <fstream> 4 #include <cstring> 5 #include <cstdlib> 6 #include <cmath> 7 using namespace std; 8 ifstream fin("hotel.in"); 9 ofstream fout("hotel.out"); 10 int Beiz[200005][20][2]={0},Hote[200005][2]={0};//0为颜色,1为价格 11 int Color[52][200005]={0};//第i种颜色的顺序排列客栈 12 int gs[52]={0};// 13 int C2[20]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288}; 14 int bh[200005]={0};//在Color数组中的编号 15 int Colors=0,Hots=0,Most=0; 16 void Bz(int cs);//倍增预处理 17 int ST(int ks,int js);//ST算法查询最小值 18 int main(void) 19 { 20 fin>>Hots>>Colors>>Most; 21 for(int i=1;i<=Hots;i++) 22 { 23 fin>>Hote[i][0]>>Hote[i][1]; 24 Color[Hote[i][0]][++gs[Hote[i][0]]]=i; 25 bh[i]=gs[Hote[i][0]]; 26 Beiz[i][0][1]=Hote[i][1]; 27 Beiz[i][0][0]=i+1; 28 } 29 Bz(1); 30 long long int Least=0ll,Fas=0ll,Zz=0ll,Gs=0ll; 31 for(int i=1;i<=Hots;i++) 32 { 33 for(int j=bh[i]+1;j<=gs[Hote[i][0]];j++) 34 { 35 Zz=Color[Hote[i][0]][j]; 36 Least=ST(i,Zz); 37 if(Least<=Most) 38 { 39 Fas+=gs[Hote[i][0]]-j+1; 40 break; 41 } 42 } 43 } 44 fout<<Fas<<" "; 45 return 0; 46 } 47 48 void Bz(int cs) 49 { 50 if(cs==20)return; 51 for(int i=1;i<=Hots;i++) 52 { 53 Beiz[i][cs][1]=min(Beiz[Beiz[i][cs-1][0]][cs-1][1],Beiz[i][cs-1][1]); 54 Beiz[i][cs][0]=Beiz[Beiz[i][cs-1][0]][cs-1][0]; 55 } 56 Bz(cs+1); 57 return; 58 } 59 60 int ST(int ks,int js) 61 { 62 int L1=0,L2=0,Mid=0; 63 double K=log((double)(js-ks))/log((double)2); 64 Mid=(int)K; 65 L1=Beiz[ks][Mid][1]; 66 L2=Beiz[js-C2[Mid]+1][Mid][1]; 67 return min(L1,L2); 68 }