제출 #783361

#제출 시각아이디문제언어결과실행 시간메모리
783361oscar1fTwo Currencies (JOI23_currencies)C++17
100 / 100
880 ms49356 KiB
#include<bits/stdc++.h> using namespace std; #define int long long const int MAX_SOM=100*1000+5,MAX_LOG=18,MAX_REQ=100*1000+5,DECA=(1<<17); int nbSom,nbCheck,nbReq,idAre,coutArg,idSom,nbRest; vector<int> adja[MAX_SOM]; int are[MAX_SOM][2]; int prof[MAX_SOM]; int pere[MAX_SOM][MAX_LOG]; int req[MAX_REQ][6]; int num[MAX_SOM]; int sousArbre[MAX_SOM][2]; vector<pair<int,int>> checkTri; vector<int> reqDeb; int cumu[2*DECA][2]; void DFS(int pos,int anci,int etage) { if (prof[pos]==0) { //cout<<pos<<" "<<anci<<" "<<etage<<endl; pere[pos][0]=anci; prof[pos]=etage; idSom++; num[pos]=idSom; sousArbre[pos][0]=idSom; for (int vois:adja[pos]) { DFS(vois,pos,etage+1); } sousArbre[pos][1]=idSom; } } int lca(int som1,int som2) { if (prof[som1]>prof[som2]) { swap(som1,som2); } for (int i=MAX_LOG-1;i>=0;i--) { if (prof[pere[som2][i]]>=prof[som1]) { som2=pere[som2][i]; } } if (som1==som2) { return som1; } for (int i=MAX_LOG-1;i>=0;i--) { if (pere[som1][i]!=pere[som2][i]) { som1=pere[som1][i]; som2=pere[som2][i]; } } return pere[som1][0]; } void ajout(int deb,int fin,int val,int idTab) { if (deb==fin) { cumu[deb][idTab]+=val; } else if (deb%2==1) { cumu[deb][idTab]+=val; ajout(deb+1,fin,val,idTab); } else if (fin%2==0) { cumu[fin][idTab]+=val; ajout(deb,fin-1,val,idTab); } else { ajout(deb/2,fin/2,val,idTab); } } int calcVal(int pos,int idTab) { int somme=0; while (pos!=0) { somme+=cumu[pos][idTab]; pos/=2; } return somme; } void addAre(int i,int coeff) { //cout<<i<<" : "<<sousArbre[are[checkTri[i].second][1]][0]<<" "<<sousArbre[are[checkTri[i].second][1]][1]<<endl; ajout(DECA+sousArbre[are[checkTri[i].second][1]][0],DECA+sousArbre[are[checkTri[i].second][1]][1],checkTri[i].first*coeff,0); ajout(DECA+sousArbre[are[checkTri[i].second][1]][0],DECA+sousArbre[are[checkTri[i].second][1]][1],coeff,1); } int calcDist(int r,int idTab) { /*cout<<endl; cout<<r<<" "<<idTab<<endl; cout<<num[req[r][0]]<<" = "<<calcVal(DECA+num[req[r][0]],idTab)<<endl; cout<<num[req[r][1]]<<" = "<<calcVal(DECA+num[req[r][1]],idTab)<<endl; cout<<num[req[r][5]]<<" = "<<calcVal(DECA+num[req[r][5]],idTab)<<endl;*/ return calcVal(DECA+num[req[r][0]],idTab)+calcVal(DECA+num[req[r][1]],idTab)-2*calcVal(DECA+num[req[r][5]],idTab); } void calc(int debInter,int finInter,int posCour,vector<int> reqCour) { if (reqCour.empty()) { return; } int midInter=(debInter+finInter+1)/2; if (finInter==-1) { midInter=-1; } /*cout<<debInter<<" "<<finInter<<" "<<posCour<<" "<<midInter<<" : "; for (int r:reqCour) { cout<<r<<" "; } cout<<endl;*/ if (posCour<midInter) { for (int i=posCour+1;i<=midInter;i++) { addAre(i,1); } } else { for (int i=posCour;i>midInter;i--) { addAre(i,-1); } } /*for (int i=1;i<2*DECA;i++) { cout<<cumu[i][0]<<" "<<cumu[i][1]<<" "; } cout<<endl;*/ if (debInter==finInter) { for (int r:reqCour) { //cout<<r<<" "<<calcDist(r,0)<<" "<<calcDist(r,1)<<endl; req[r][4]=calcDist(r,1); } } else { vector<int> reqSous,reqSur; for (int r:reqCour) { //cout<<r<<" : "<<calcDist(r,0)<<endl; if (calcDist(r,0)>req[r][3]) { reqSous.push_back(r); } else { reqSur.push_back(r); } } calc(debInter,midInter-1,midInter,reqSous); calc(midInter,finInter,midInter,reqSur); } if (posCour<midInter) { for (int i=posCour+1;i<=midInter;i++) { addAre(i,-1); } } else { for (int i=posCour;i>midInter;i--) { addAre(i,1); } } } signed main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin>>nbSom>>nbCheck>>nbReq; for (int i=1;i<nbSom;i++) { cin>>are[i][0]>>are[i][1]; adja[are[i][0]].push_back(are[i][1]); adja[are[i][1]].push_back(are[i][0]); } DFS(1,0,1); /*for (int i=1;i<=nbSom;i++) { cout<<i<<" : "<<num[i]<<" "<<sousArbre[i][0]<<" "<<sousArbre[i][1]<<" "<<pere[i][0]<<" "<<prof[i]<<endl; }*/ for (int j=1;j<MAX_LOG;j++) { for (int i=0;i<=nbSom;i++) { pere[i][j]=pere[pere[i][j-1]][j-1]; } } for (int i=1;i<nbSom;i++) { if (prof[are[i][0]]>prof[are[i][1]]) { swap(are[i][0],are[i][1]); } } for (int i=0;i<nbCheck;i++) { cin>>idAre>>coutArg; checkTri.push_back({coutArg,idAre}); } sort(checkTri.begin(),checkTri.end()); for (int i=0;i<nbReq;i++) { cin>>req[i][0]>>req[i][1]>>req[i][2]>>req[i][3]; reqDeb.push_back(i); req[i][5]=lca(req[i][0],req[i][1]); } calc(-1,nbCheck-1,-1,reqDeb); for (int i=0;i<nbCheck;i++) { addAre(i,1); } for (int i=0;i<nbReq;i++) { nbRest=calcDist(i,1)-req[i][4]; //cout<<i<<" : "<<req[i][4]<<" "<<calcDist(i,1)<<" "; cout<<max(req[i][2]-nbRest,(int)-1)<<"\n"; } 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...