Submission #1066410

#TimeUsernameProblemLanguageResultExecution timeMemory
1066410oscar1fRailway Trip (JOI17_railway_trip)C++17
100 / 100
1136 ms326320 KiB
#include<bits/stdc++.h> using namespace std; #define int long long const int TAILLE_MAX=100*1000+5,INFINI=1000*1000*1000,DECA=(1<<17),MAX_INTER=900*1000+5,MAX_LOG=20; int nbVal,typeMaxi,nbReq,nbInter; int val[TAILLE_MAX]; vector<int> posVal[TAILLE_MAX]; set<int> plusGrand; set<int>::iterator it; int supVois[TAILLE_MAX][2]; int distVois[TAILLE_MAX][2]; int numEgau[TAILLE_MAX]; int arbreSom[2*DECA]; vector<pair<int,int>> interInteress; unordered_map<int,int> corres; int suiv[MAX_INTER][MAX_LOG][2]; int hautInter[MAX_INTER]; int hache(int deb,int fin) { return deb*TAILLE_MAX+fin; } void ajout(int pos) { pos+=DECA; while (pos>0) { arbreSom[pos]++; pos/=2; } } int calcInter(int deb,int fin) { if (deb==fin) { return arbreSom[deb]; } if (deb%2==1) { return arbreSom[deb]+calcInter(deb+1,fin); } if (fin%2==0) { return arbreSom[fin]+calcInter(deb,fin-1); } return calcInter(deb/2,fin/2); } void calcSuiv(int deb,int fin,int diff) { int distGau=0,distDro=0,caseTab=corres[hache(deb,fin)]+nbInter*diff; hautInter[caseTab]=min(val[deb],val[fin]); if (diff==0) { distGau=1; } else if (diff==2) { distDro=1; } int voisGau=deb,voisDro=fin,pos,hautSuiv=min(val[deb],val[fin])+1; //cout<<caseTab<<" "; if (hautSuiv>typeMaxi) { //cout<<"#"<<caseTab%nbInter<<" "; suiv[caseTab][0][0]=caseTab; suiv[caseTab][0][1]=0; } else { pos=voisGau; if (val[pos]<hautSuiv) { voisGau=supVois[pos][0]; distGau+=distVois[pos][0]; } pos=voisDro; if (val[pos]<hautSuiv) { voisDro=supVois[pos][1]; distDro+=distVois[pos][1]; } distGau=min(distGau,distDro+1); distDro=min(distDro,distGau+1); int suivDiff,minDist=min(distGau,distDro); distGau-=minDist; distDro-=minDist; if (distGau==1 and distDro==0) { suivDiff=0; } else if (distGau==0 and distDro==0) { suivDiff=1; } else { suivDiff=2; } suiv[caseTab][0][0]=corres[hache(voisGau,voisDro)]+nbInter*suivDiff; suiv[caseTab][0][1]=minDist; } } pair<int,int> findInter(int pos,int hautMax) { if (hautInter[pos]>=hautMax) { return {pos,0}; } int distParc=0; for (int i=MAX_LOG-1;i>=0;i--) { if (hautInter[suiv[pos][i][0]]<hautMax) { distParc+=suiv[pos][i][1]; pos=suiv[pos][i][0]; } } distParc+=suiv[pos][0][1]; pos=suiv[pos][0][0]; return {pos,distParc}; } signed main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin>>nbVal>>typeMaxi>>nbReq; for (int i=1;i<=nbVal;i++) { cin>>val[i]; numEgau[i]=posVal[val[i]].size(); posVal[val[i]].push_back(i); interInteress.push_back({i,i}); } plusGrand.insert(-INFINI); plusGrand.insert(INFINI); for (int i=typeMaxi;i>=1;i--) { for (int j:posVal[i]) { it=plusGrand.lower_bound(j); if (abs((*it))!=INFINI) { supVois[j][1]=(*it); } it--; if (abs((*it))!=INFINI) { supVois[j][0]=(*it); } } for (int j:posVal[i]) { plusGrand.insert(j); ajout(j); } for (int j:posVal[i]) { if (supVois[j][0]!=0) { distVois[j][0]=calcInter(DECA+1,DECA+j)-calcInter(DECA+1,DECA+supVois[j][0]); } if (supVois[j][1]!=0) { distVois[j][1]=calcInter(DECA+1,DECA+supVois[j][1])-calcInter(DECA+1,DECA+j); } it=plusGrand.lower_bound(j); it++; if (abs((*it))!=INFINI and val[(*it)]>i) { interInteress.push_back({j,abs(*it)}); } it--; it--; if (abs((*it))!=INFINI) { interInteress.push_back({abs(*it),j}); } } } //cout<<interInteress.size()<<endl; nbInter=interInteress.size(); for (int i=0;i<nbInter;i++) { //cout<<interInteress[i].first<<" "<<interInteress[i].second<<endl; corres[hache(interInteress[i].first,interInteress[i].second)]=i; } for (int i=0;i<nbInter;i++) { for (int j=0;j<3;j++) { calcSuiv(interInteress[i].first,interInteress[i].second,j); } //cout<<interInteress[i].first<<" "<<interInteress[i].second<<" : "<<interInteress[suiv[i][0][0]%nbInter].first<<" "<<interInteress[suiv[i][0][0]%nbInter].second<<endl; } for (int j=1;j<MAX_LOG;j++) { for (int i=0;i<3*nbInter;i++) { suiv[i][j][0]=suiv[suiv[i][j-1][0]][j-1][0]; suiv[i][j][1]=suiv[i][j-1][1]+suiv[suiv[i][j-1][0]][j-1][1]; } } int deb,fin,rep,hautMax,debDicho,finDicho,midDicho; pair<int,int> interGau,interDro; for (int ireq=0;ireq<nbReq;ireq++) { cin>>deb>>fin; if (deb>fin) { swap(deb,fin); } debDicho=max(val[deb],val[fin])+1; finDicho=typeMaxi+1; while (debDicho!=finDicho) { midDicho=(debDicho+finDicho)/2; interGau=findInter(corres[hache(deb,deb)]+nbInter,midDicho); interDro=findInter(corres[hache(fin,fin)]+nbInter,midDicho); if (interGau.first%nbInter==interDro.first%nbInter) { finDicho=midDicho; } else { debDicho=midDicho+1; } } hautMax=debDicho; if (hautMax<=typeMaxi) { interGau=findInter(corres[hache(deb,deb)]+nbInter,hautMax); interDro=findInter(corres[hache(fin,fin)]+nbInter,hautMax); rep=interGau.second+interDro.second+min((interGau.first/nbInter==0)+(interDro.first/nbInter==0), (interGau.first/nbInter==2)+(interDro.first/nbInter==2)); } else { rep=INFINI; } //cout<<"!"<<hautMax-1<<" "<<rep<<endl; interGau=findInter(corres[hache(deb,deb)]+nbInter,hautMax-1); interDro=findInter(corres[hache(fin,fin)]+nbInter,hautMax-1); rep=min(rep,interGau.second+(interGau.first/nbInter==2)+interDro.second+(interDro.first/nbInter==0)+ numEgau[interInteress[interDro.first%nbInter].first]-numEgau[interInteress[interGau.first%nbInter].second]); /*if (rep<=0) { cout<<deb<<" "<<fin<<endl; }*/ cout<<rep-1<<"\n"; } //cout<<endl; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...