Submission #1235254

#TimeUsernameProblemLanguageResultExecution timeMemory
1235254oscar1fSpring cleaning (CEOI20_cleaning)C++20
100 / 100
389 ms84240 KiB
#include<bits/stdc++.h> using namespace std; #define int long long const int MAX_SOM=100*1000+5,MAX_LOG=19,DECA=(1<<17); int nbSom,nbReq,racine,numSuf,numEuler,nbPair,nbImp,rep,plusFeuil; vector<int> adja[MAX_SOM]; int parcSuf[MAX_SOM]; bool dv[MAX_SOM],dv2[MAX_SOM]; int borneEuler[MAX_SOM][2]; //renum int maxSuiv[3*MAX_SOM][MAX_LOG]; //renum int euler[3*MAX_SOM]; //renum int corresp[MAX_SOM]; //renum int puis2Inf[3*MAX_SOM]; int anci[MAX_SOM]; int nbSurPair[MAX_SOM],nbSurImp[MAX_SOM]; vector<int> listeFils[MAX_SOM]; int nbFeuil,nbModif; int feuilSous[MAX_SOM]; int pere[MAX_SOM]; set<int> somModif; int nbNouv[MAX_SOM]; int debSous[MAX_SOM]; //renum unordered_map<int,int> arb[2]; void DFS(int pos) { if (!dv[pos]) { dv[pos]=true; int deb=numSuf+1; for (int i:adja[pos]) { DFS(i); } numSuf++; parcSuf[pos]=numSuf; debSous[numSuf]=deb; corresp[numSuf]=pos; } } void DFS2(int pos,int anci) { if (!dv2[pos]) { pere[pos]=anci; dv2[pos]=true; numEuler++; borneEuler[parcSuf[pos]][0]=numEuler; euler[numEuler]=parcSuf[pos]; for (int i:adja[pos]) { if (!dv2[i]) { numEuler++; euler[numEuler]=parcSuf[pos]; listeFils[pos].push_back(i); DFS2(i,pos); } } numEuler++; borneEuler[parcSuf[pos]][1]=numEuler; euler[numEuler]=parcSuf[pos]; } } int lca(int som1,int som2) { int deb=min(borneEuler[som1][0],borneEuler[som2][0]),fin=max(borneEuler[som1][1],borneEuler[som2][1]); //cout<<deb<<" "<<fin<<" "<<puis2Inf[fin-deb]<<endl; return max(maxSuiv[deb][puis2Inf[fin-deb]],maxSuiv[fin-(1<<puis2Inf[fin-deb])+1][puis2Inf[fin-deb]]); } int calcFeuille(int pos) { if (adja[pos].size()==1) { feuilSous[pos]=1; nbFeuil++; } else { for (int i:listeFils[pos]) { feuilSous[pos]+=calcFeuille(i); } } return feuilSous[pos]; } void calcDessus(int pos) { if (nbSurPair[pos]!=-1) { return; } calcDessus(pere[pos]); nbSurPair[pos]=nbSurPair[pere[pos]]; nbSurImp[pos]=nbSurImp[pere[pos]]; if (feuilSous[pos]%2==0) { nbSurPair[pos]++; nbPair++; } else { nbSurImp[pos]++; nbImp++; } } void ajout(int pos,int val,int id) { pos+=DECA; while (pos>0) { arb[id][pos]+=val; pos/=2; } } int calcSom(int deb,int fin,int id) { if (deb==fin) { return arb[id][deb]; } if (deb%2==1) { return arb[id][deb]+calcSom(deb+1,fin,id); } if (fin%2==0) { return arb[id][fin]+calcSom(deb,fin-1,id); } return calcSom(deb/2,fin/2,id); } signed main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin>>nbSom>>nbReq; for (int i=0;i<nbSom-1;i++) { int debAre,finAre; cin>>debAre>>finAre; adja[debAre].push_back(finAre); adja[finAre].push_back(debAre); } for (int i=1;i<=nbSom;i++) { if ((int)adja[i].size()>1) { racine=i; } } DFS(racine); DFS2(racine,racine); for (int i=0;i<3*nbSom;i++) { maxSuiv[i][0]=euler[i]; } for (int j=1;j<MAX_LOG;j++) { for (int i=0;i<3*nbSom;i++) { maxSuiv[i][j]=max(maxSuiv[i][j-1],maxSuiv[min(i+(1<<(j-1)),3*MAX_SOM-1)][j-1]); } } puis2Inf[1]=0; for (int i=2;i<3*nbSom;i++) { puis2Inf[i]=puis2Inf[i/2]+1; } /*for (int i=1;i<3*nbSom;i++) { cout<<puis2Inf[i]<<" "; } cout<<endl; for (int i=1;i<3*nbSom;i++) { cout<<euler[i]<<" "; } cout<<endl; for (int i=1;i<=nbSom;i++) { cout<<i<<" : "<<parcSuf[i]<<endl; } for (int i=1;i<=nbSom;i++) { cout<<i<<" : "<<pere[i]<<endl; } cout<<endl; for (int i=1;i<=nbSom;i++) { cout<<i<<" : "<<parcSuf[i]<<" "<<debSous[parcSuf[i]]<<endl; }*/ calcFeuille(racine); for (int i=1;i<=nbSom;i++) { nbSurPair[i]=-1; nbSurImp[i]=-1; } nbSurImp[racine]=0; nbSurPair[racine]=0; for (int i=1;i<=nbSom;i++) { calcDessus(i); //cout<<i<<" : "<<nbSurImp[i]<<" "<<nbSurPair[i]<<endl; } //cout<<nbImp<<" "<<nbPair<<" "<<nbFeuil<<endl; for (int ireq=0;ireq<nbReq;ireq++) { cin>>nbModif; somModif.clear(); for (int i=0;i<nbModif;i++) { int nouv; cin>>nouv; somModif.insert(nouv); nbNouv[nouv]++; } plusFeuil=0; for (int i:somModif) { if (adja[i].size()==1) { plusFeuil++; nbNouv[i]--; } } if ((nbFeuil+nbModif-plusFeuil)%2==1) { cout<<-1<<"\n"; } else { rep=nbImp+2*nbPair+nbModif; //cout<<"?"<<rep<<endl; vector<int> somAj; arb[0].clear(); arb[1].clear(); for (int i:somModif) { if (nbNouv[i]%2==1) { somAj.push_back(parcSuf[i]); ajout(parcSuf[i],1,0); } } sort(somAj.begin(),somAj.end()); set<int> listeLCA; for (int i:somAj) { listeLCA.insert(i); } for (int i=0;i<(int)somAj.size()-1;i++) { listeLCA.insert(lca(somAj[i],somAj[i+1])); } for (int i:listeLCA) { int obj=calcSom(DECA+debSous[i],DECA+i,0)%2; int dejaFait=calcSom(DECA+debSous[i],DECA+i,1); //cout<<i<<" : "<<obj<<" "<<dejaFait<<" "<<nbSurImp[i]<<" "<<nbSurPair[i]<<endl; rep+=(obj-dejaFait)*(nbSurImp[corresp[i]]-nbSurPair[corresp[i]]); ajout(i,obj-dejaFait,1); } /*for (int i=1;i<=nbSom;i++) { int obj=calcSom(DECA+debSous[i],DECA+i,0)%2; int dejaFait=calcSom(DECA+debSous[i],DECA+i,1); rep+=(obj-dejaFait)*(nbSurImp[corresp[i]]-nbSurPair[corresp[i]]); ajout(i,obj-dejaFait,1); //cout<<corresp[i]<<" "<<obj<<" "<<dejaFait<<" "<<nbSurImp[corresp[i]]<<" "<<nbSurPair[corresp[i]]<<endl; }*/ cout<<rep<<"\n"; } for (int i:somModif) { nbNouv[i]=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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...