Submission #1182912

#TimeUsernameProblemLanguageResultExecution timeMemory
1182912mertbbmMaking Friends on Joitter is Fun (JOI20_joitter2)C++20
100 / 100
377 ms66748 KiB
#include <bits/stdc++.h> using namespace std; #define int long long #define ld long double #define show(x,y) cout << y << " " << #x << endl; #define show2(x,y,i,j) cout << y << " " << #x << " " << j << " " << #i << endl; #define show3(x,y,i,j,p,q) cout << y << " " << #x << " " << j << " " << #i << " " << q << " " << #p << endl; #define show4(x,y) for(auto it:y) cout << it << " "; cout << #x << endl; typedef pair<int,int>pii; mt19937_64 rng(chrono::system_clock::now().time_since_epoch().count()); set<pii>in[100005]; set<pii>out[100005]; int counter=0; bool connect(int a, int b){ //out[a].find(b)!=out[a].end()&&out[b].find(a)!=out[b].end() auto it=out[a].lower_bound({b,0}); auto it2=out[b].lower_bound({a,0}); if(it!=out[a].end()&&it2!=out[b].end()&&it->first==b&&it2->first==a) return true; return false; } int f(int a){ return a*(a-1); } struct DSU{ vector<int>e; void init(int n){ e=vector<int>(n,-1); } int get(int x){ return e[x]<0?x:e[x]=get(e[x]); } int sz(int x){ return -e[get(x)]; } bool sameSet(int x, int y){ return get(x)==get(y); } bool unite(int x, int y){ x=get(x); y=get(y); if(x==y) return 1; if(e[x]>e[y]){ swap(x,y); //swap(in[x],in[y]); //swap(out[x],out[y]); } //show2(x,x,y,y); counter-=(-e[x])*(in[x].size()); counter-=(-e[y])*(in[y].size()); counter-=f(-e[x]); counter-=f(-e[y]); //show(done,1); //check if they have edge pointing to each other vector<pii>dlt; for(auto it:out[y]){ //show(it,it); if(sameSet(it.first,x)) dlt.push_back(it); } for(auto it:dlt){ out[y].erase(it); in[it.first].erase({y,it.second}); } //show4(dlt,dlt); dlt.clear(); for(auto it:in[y]){ if(sameSet(it.first,x)) dlt.push_back(it); } for(auto it:dlt){ in[y].erase(it); out[it.first].erase({y,it.second}); } //show4(dlt,dlt); //show(done,2); //y something x vector<int>merge; for(auto it:in[y]){ auto ite=out[x].lower_bound({it.first,0}); if(ite!=out[x].end()&&ite->first==it.first){ merge.push_back(it.first); } //if(out[x].find(it)!=out[x].end()){ //merge.push_back(it.first); //} } for(auto it:out[y]){ auto ite=in[x].lower_bound({it.first,0}); if(ite!=in[x].end()&&ite->first==it.first){ merge.push_back(it.first); } //if(in[x].find(it)!=in[x].end()){ //merge.push_back(it.first); //} } //show(done,3); //for(int i=1;i<=4;i++){ //show(i,i); //show4(in[i],in[i]); //show4(out[i],out[i]); //} //show(y,y); //upd all the nodes pointing to y dlt.clear(); for(auto it:out[y]){ //cout << it << endl; in[it.first].erase({y,it.second}); //out[y].erase(it); in[it.first].insert({x,it.second}); out[x].insert(it); //dlt.push_back(it); } //for(auto it:dlt) out[y].erase(it); //show(done,5); for(auto it:in[y]){ //cout << it << " *" << endl; out[it.first].erase({y,it.second}); //in[y].erase(it); out[it.first].insert({x,it.second}); in[x].insert(it); } in[y].clear(); out[y].clear(); //show(done,4); e[x]+=e[y]; e[y]=x; counter+=f(-e[x]); counter+=(-e[x])*(in[x].size()); for(auto it:merge) unite(x,it); return 0; } }; void solve(){ int n,m; cin >> n >> m; int a,b; DSU dsu; dsu.init(n+5); for(int x=0;x<m;x++){ cin >> a >> b; int og=a; a=dsu.get(a); b=dsu.get(b); if(a!=b&&out[a].find({b,og})==out[a].end()){ //show(sz,in[b].size()); //counter-=in[b].size()*dsu.sz(b); in[b].insert({a,og}); out[a].insert({b,og}); //counter+=in[b].size()*dsu.sz(b); //show2(x,x,sz,dsu.sz(b)); counter+=dsu.sz(b); //check (a,b) //show(counter,counter); //cout << counter << " " << x << " counter\n"; if(connect(a,b)){ dsu.unite(a,b); } } //for(int y=1;y<=n;y++){ ////show(y,y); //show4(in[y],in[y]); //show4(out[y],out[y]); //} cout << counter << "\n"; } } int32_t main(){ ios::sync_with_stdio(0); cin.tie(0); int t=1; //cin >> t; while(t--){ solve(); } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...