제출 #1336352

#제출 시각아이디문제언어결과실행 시간메모리
1336352boclobanchatIdeal city (IOI12_city)C++20
0 / 100
54 ms11680 KiB
#include<bits/stdc++.h>
using namespace std;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
const int MAXN=1e5+5;
const long long mod=1e9;
vector< pair<int,int> > vqx,vqy,vi[MAXN*4];
vector<int> ds[MAXN];
map< int,vector<int> > mpx,mpy;
map< pair<int,int>,int > mp;
int dsu[MAXN],cnt[MAXN];
long long dp[MAXN],F[MAXN],ans=0;
stack< pair<int,int> > st;
bool ck[MAXN];
vector< pair<int,int> > P;
pair<int,int> G[MAXN];
queue<int> Q;
int root(int i)
{
	if(!dsu[i]) return i;
	return root(dsu[i]);
}
void merge(int i,int j)
{
	if((i=root(i))==(j=root(j)))
	{
		st.push({-1,-1});
		return ;
	}
	if(cnt[i]<cnt[j]) swap(i,j);
	dsu[j]=i,cnt[i]+=cnt[j],st.push({i,j});
}
void rollback()
{
	int i=st.top().first,j=st.top().second;
	st.pop();
	if(i<0) return ;
	cnt[i]-=cnt[j],dsu[j]=0;
}
void dfs(int x,int y)
{
	int pre=mp[{x,y}];
	ck[pre]=true;
	for(int i=0;i<4;i++)
	{
		int a=x+dx[i],b=y+dy[i],res=mp[{a,b}];
		if(res&&!ck[res])
		{
			if(i<2) vqx.push_back({pre,res});
			else vqy.push_back({pre,res});
			ds[pre].push_back(res);
			dfs(a,b);
		}
	}
}
void update(int l,int r,int u,int v,pair<int,int> val,int pos)
{
	if(v<l||r<u) return ;
	if(u<=l&&r<=v)
	{
		vi[pos].push_back(val);
		return ;
	}
	int mid=(l+r)/2;
	update(l,mid,u,v,val,pos*2);
	update(mid+1,r,u,v,val,pos*2+1);
}
void solve(int l,int r,int pos)
{
	for(auto v:vi[pos]) merge(v.first,v.second);
	if(l==r) G[l]={cnt[root(P[l].first)],cnt[root(P[l].second)]};
	else
	{
		int mid=(l+r)/2;
		solve(l,mid,pos*2);
		solve(mid+1,r,pos*2+1);
	}
	for(auto v:vi[pos]) rollback();
	vi[pos].clear();
}
void dfs2(int i)
{
	ans+=F[i];
	for(auto v:ds[i])
	{
		F[v]+=F[i];
		dfs2(v);
	}
}
int DistanceSum(int N,int *X,int *Y)
{
	for(int i=1;i<=N;i++) cnt[i]=1;
	for(int i=0;i<N;i++) mpx[X[i]].push_back(Y[i]),mpy[Y[i]].push_back(X[i]),mp[{X[i],Y[i]}]=i+1;
	for(auto v:mpx) sort(v.second.begin(),v.second.end());
	for(auto v:mpy) sort(v.second.begin(),v.second.end());
	for(int i=1;i<=N;i++) dp[i]=mod;
	dp[1]=0,Q.push(1);
	while(!Q.empty())
	{
		int a=Q.front();
		Q.pop();
		for(int i=0;i<4;i++)
		{
			int res=mp[{X[a-1]+dx[i],Y[a-1]+dy[i]}];
			if(res&&dp[res]==mod) dp[res]=dp[a]+1,Q.push(res);
		}
	}
	for(int i=1;i<=N;i++) F[1]+=dp[i];
	dfs(X[0],Y[0]);
	int m=0;
	if(vqx.size())
	{
		for(auto v:mpx)
		{
			int pre=-1;
			for(auto u:v.second)
			{
				if(pre+1==u) merge(mp[{v.first,pre}],mp[{v.first,u}]);
				pre=u;
			}
		}
		for(auto v:vqx)
		{
			pair<int,int> res={root(v.first),root(v.second)};
			if(res.first>res.second) swap(res.first,res.second);
			P.push_back(res);
		}
		sort(P.begin(),P.end());
		P.erase(unique(P.begin(),P.end()),P.end());
		m=P.size();
		for(int i=0;i<m;i++)
		{
			update(0,m-1,0,i-1,P[i],1);
			update(0,m-1,i+1,m-1,P[i],1);
		}
		solve(0,m-1,1);
		for(auto v:vqx)
		{
			int he=1;
			pair<int,int> res={root(v.first),root(v.second)};
			if(res.first>res.second) swap(res.first,res.second),he=-1;
			int pos=lower_bound(P.begin(),P.end(),res)-P.begin();
			F[v.second]=(G[pos].first-G[pos].second)*he;
		}
		while(!st.empty()) rollback();
		P.clear();
	}
	if(vqy.size())
	{
		for(auto v:mpy)
		{
			int pre=-1;
			for(auto u:v.second)
			{
				if(pre+1==u) merge(mp[{pre,v.first}],mp[{u,v.first}]);
				pre=u;
			}
		}
		for(auto v:vqy)
		{
			pair<int,int> res={root(v.first),root(v.second)};
			if(res.first>res.second) swap(res.first,res.second);
			P.push_back(res);
		}
		sort(P.begin(),P.end());
		P.erase(unique(P.begin(),P.end()),P.end());
		m=P.size();
		for(int i=0;i<m;i++)
		{
			update(0,m-1,0,i-1,P[i],1);
			update(0,m-1,i+1,m-1,P[i],1);
		}
		solve(0,m-1,1);
		for(auto v:vqy)
		{
			int he=1;
			pair<int,int> res={root(v.first),root(v.second)};
			if(res.first>res.second) swap(res.first,res.second),he=-1;
			int pos=lower_bound(P.begin(),P.end(),res)-P.begin();
			F[v.second]=(G[pos].first-G[pos].second)*he;
		}
		while(!st.empty()) rollback();
		P.clear();
	}
	dfs2(1);
	return (ans/2)%mod;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...