제출 #1267126

#제출 시각아이디문제언어결과실행 시간메모리
1267126ThylOneWerewolf (IOI18_werewolf)C++20
100 / 100
393 ms101756 KiB
#include "werewolf.h" #include <iostream> #include <cmath> #include <vector> #include <utility> #include <cassert> using namespace std; struct unionFind{ vector<int> chef, in, out; vector<vector<int>> links; int e = 0; inline int find(int x){ if(chef[x] == x)return x; return chef[x] = find(chef[x]); } inline pair<int,int> getCompoConnexe(int x){ return make_pair(in[x], out[x]); } //l'ordre compte tres fort ici void make_A_in_B(int a, int b){ a = find(a); b = find(b); if(a != b){ links[b].push_back(a); chef[a] = b; } } void dfs(int node){ in[node] = ++e; for(int v:links[node]) dfs(v); out[node] = ++e; } void computeEuleurTour(){ e = 0; for(int i = 0 ; i < chef.size() ; i++){ if(find(i) == i){ dfs(i); } } } unionFind(int n){ chef.resize(n); in.resize(n); out.resize(n); links.resize(n); for(int i=0;i<n;i++)chef[i]=i; } }; struct req{ int d,f,id; req()=default; req(int _d, int _f, int _id):d(_d), f(_f), id(_id){} }; struct Fenwick{ vector<int> vals; Fenwick(int n){ vals.resize(n+1,0); } #define LSONE(x) ((x)&(-x)) void updatePoint(int pos, int v){ while(pos < vals.size()){ vals[pos] += v; pos += LSONE(pos); } } int inline get(int i){ int re = 0; while(i){ re += vals[i]; i -= LSONE(i); } return re; } int inline get(int i, int j){ return get(j) - get(i-1); } }; vector<int> check_validity(int N, vector<int> X, vector<int> Y, vector<int> S, vector<int> E, vector<int> L, vector<int> R) { //liste d'adjacence vector<int> links[N]; for(int e = 0 ; e < X.size() ; e++){ links[X[e]].push_back(Y[e]); links[Y[e]].push_back(X[e]); } int Q = S.size(); vector<pair<int,int>> eventH[N], eventW[N]; for(int i = 0 ; i < Q ; i++){ eventH[L[i]].emplace_back(S[i], i); eventW[R[i]].emplace_back(E[i], i); } vector<int> queryS(Q), queryE(Q); unionFind ufW(N), ufH(N); for(int city = 0 ; city < N ; city++){ for(int u:links[city])if(u < city){ ufW.make_A_in_B(u, city); } //on garde en memoire le chef a ce moment city for(auto event:eventW[city]){ queryE[event.second] = ufW.find(event.first); } } for(int city = N - 1 ; city >= 0 ; city--){ for(int u:links[city])if(u > city){ ufH.make_A_in_B(u, city); } //on garde en memoire le chef a ce moment city for(auto event:eventH[city]){ queryS[event.second] = ufH.find(event.first); } } //conpute les euleurs tours ufH.computeEuleurTour(); ufW.computeEuleurTour(); const int W = 1 + 2*N; vector<int> addY[W];//les events pour ajouter les pts dans le fenwick vector<req> reqs[W]; for(int i = 0 ; i < N ; i++){ addY[ufH.in[i]].push_back(ufW.out[i]); } for(int r = 0 ; r < Q ; r++){ auto humanP = ufH.getCompoConnexe(queryS[r]); auto werewolfP = ufW.getCompoConnexe(queryE[r]); //pour faire de l'inclusion exclusion reqs[humanP.first - 1].emplace_back(werewolfP.first, werewolfP.second, r); reqs[humanP.second ].emplace_back(werewolfP.first, werewolfP.second, r); } vector<int> ans(Q,-1); Fenwick ft(W); for(int x = 0 ; x < W ; x++){ //On met les points sur la D for(int y:addY[x])ft.updatePoint(y, 1); for(auto R:reqs[x]){ if(ans[R.id] == -1){//prefix left ans[R.id] = ft.get(R.d, R.f); }else{//prefi right ans[R.id] = ft.get(R.d, R.f) - ans[R.id]; } } } for(int &i:ans)if(i>0)i=1; return ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...