Submission #211904

#TimeUsernameProblemLanguageResultExecution timeMemory
211904ryanseeMaking Friends on Joitter is Fun (JOI20_joitter2)C++14
100 / 100
1012 ms94968 KiB
#include "bits/stdc++.h" using namespace std; #define FAST ios_base::sync_with_stdio(false); cin.tie(0); #define pb push_back #define eb emplace_back #define ins insert #define ph push #define f first #define s second #define cbr cerr << "hi\n" #define mmst(x, v) memset((x), v, sizeof ((x))) #define siz(x) ll(x.size()) #define all(x) (x).begin(), (x).end() #define lbd(x, y) lower_bound(all(x), y) #define ubd(x, y) upper_bound(all(x), y) mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); //can be used by calling rng() or shuffle(A, A+n, rng) inline long long rand(long long x, long long y) { return (rng() % (y+1-x)) + x; } //inclusivesss string inline to_string(char c) {string s(1,c);return s;} template<typename T> inline T gcd(T a,T b){ return a==0?llabs(b):gcd(b%a,a); } typedef long long ll; typedef long double ld; #define FOR(i,s,e) for(ll i=s;i<=ll(e);++i) #define DEC(i,s,e) for(ll i=s;i>=ll(e);--i) typedef pair<ll,ll>pi; typedef pair<ll,pi>spi; typedef pair<pi,pi>dpi; #define LLINF ((long long)1e18) #define INF int(1e9+1e6) #define MAXN (300006) ll n,m,ans,fake[MAXN],deg[MAXN]; // rmbr to pass down everything including fake and deg!!!! struct ufds_ { int p[MAXN],sz[MAXN]; ufds_() { FOR(i,0,MAXN-1) p[i]=i, sz[i]=1; } void merge(int x,int y){ x=find(x),y=find(y); assert(x^y); p[x]=y, sz[y]+=sz[x]; } int find(int x) { return (p[x]==x)?x:p[x]=find(p[x]); } ll get_sz(ll x) { return sz[find(x)]; } } ufds; ll nc2(ll n){ return n*(n-1); } set<ll> v[MAXN],bck[MAXN]; map<ll,ll>howmany[MAXN]; queue<pi> q; int main(){ FAST cin>>n>>m; auto solve=[&](ll a,ll b){ if(a==b)return; assert(v[a].count(b)), assert(v[b].count(a)); v[a].erase(b), v[b].erase(a); ans-=nc2(ufds.get_sz(b)), ans-=nc2(ufds.get_sz(a)), ans+=nc2(ufds.get_sz(a)+ufds.get_sz(b)); ans-=ufds.get_sz(a)*howmany[a][b], ans-=ufds.get_sz(b)*howmany[b][a]; // assert(howmany[b][a]==0); // check if need swap; if(siz(v[a])+siz(bck[a])>siz(v[b])+siz(bck[b]))swap(a,b); // swap(a,b); fake[b]+=howmany[b][a], howmany[b][a]=0; for(auto i:v[a]) { assert(i==ufds.find(i)); howmany[i][b]+=howmany[i][a]; howmany[i].erase(a); v[b].ins(i); if(v[i].count(b)) { q.emplace(b, i); } } v[a].clear(); ans+=ufds.get_sz(a)*(siz(bck[b])-fake[b]); for(auto i:bck[a]){ if(ufds.find(i)==b||ufds.find(i)==a) continue; if(v[b].count(ufds.find(i))){ q.emplace(b, i); } v[ufds.find(i)].erase(a), v[ufds.find(i)].ins(b); if(bck[b].find(i)!=bck[b].end()) ans-=ufds.get_sz(a); else bck[b].ins(i), howmany[b][ufds.find(i)]++, ans+=ufds.get_sz(b); } howmany[a].clear(); bck[a].clear(); deg[b]+=deg[a]; ufds.merge(a,b); }; FOR(i,1,m){ ll a,b;cin>>a>>b; ll oa=a; a=ufds.find(a), b=ufds.find(b); if(a==b){ cout<<ans<<'\n'; continue; } if(v[b].find(a)!=v[b].end()){ assert(bck[b].find(oa)==bck[b].end()); v[a].ins(b); bck[b].ins(oa); ++ howmany[b][a]; ans+=ufds.get_sz(b); q.emplace(a, b); while(q.size()){ solve(ufds.find(q.front().f),ufds.find(q.front().s)); q.pop(); } }else{ if(bck[b].find(oa)==bck[b].end()){ v[a].ins(b), bck[b].ins(oa); ++ deg[a], ++deg[b]; ++ howmany[b][a]; // [receiving end][giving end] ans+=ufds.get_sz(b); } } cout<<ans<<'\n'; } } /* 3 4 3 2 1 3 2 1 1 2 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...