题解:P10097 [ROIR 2023 Day 1] 彩点
考虑转化成图论问题。
我们从
那么建完图之后,一个点
考虑缩点,第一问是简单的,第二问直接对于每个点维护一个 bitset,第
时间复杂度
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,t,m,x[1005],y[1005],low[1000005],dfn[1000005],st[1000005],top,ins[1000005],cntt,fr[1000005],cnt,vis[1005],fff[1005],co[1000005],in[1000005];
vector<int>ve[1000005],ve2[1000005];
bitset<1005>f[1000005],g[1000005];
queue<int>qu;
struct ee{
int u,v;
}e[1000005];
struct nd{
int k,dis,id;
long double xl;
friend bool operator<(const nd&a,const nd&b){
if(a.k!=b.k)return a.k<b.k;
if(a.xl-b.xl>1e-18||b.xl-a.xl>1e-18)return a.xl-b.xl<1e-18;
return a.dis<b.dis;
}
friend bool operator>(const nd&a,const nd&b){
return b<a;
}
}a[1005];
long double slope(int i,int j){
if(x[i]==x[j]){
return (int)-1e18;
}
return (long double)(y[i]-y[j])/(x[i]-x[j]);
}
int dist(int i,int j){
return(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
}
int get(int i,int j){
return(i-1)*n+j;
}
void tarjan(int u){
low[u]=dfn[u]=++cnt,st[++top]=u,ins[u]=1;
for(int v:ve[u]){
if(!dfn[v])tarjan(v),low[u]=min(low[u],low[v]);
else if(ins[v])low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
cntt++;
do{
fr[st[top]]=cntt;
ins[st[top]]=0;
}while(st[top--]!=u);
}
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>t;
for(int i=1;i<=n;i++)cin>>x[i]>>y[i];
for(int i=1;i<=n;i++){
int cnt=0;
for(int j=1;j<=n;j++)if(i!=j){
cnt++,a[cnt].dis=dist(i,j),a[cnt].xl=slope(i,j),a[cnt].id=j;
if(x[j]>x[i]&&y[j]>=y[i])a[cnt].k=1;
if(x[j]<=x[i]&&y[j]>y[i])a[cnt].k=2;
if(x[j]<x[i]&&y[j]<=y[i])a[cnt].k=3;
if(x[j]>=x[i]&&y[j]<y[i])a[cnt].k=4;
}
sort(a+1,a+cnt+1);
for(int j=1;j<=cnt;j++){
nd xx=a[j];xx.dis=-1e18;
if(xx.k<=2)xx.k+=2;
else xx.k-=2;
int now=lower_bound(a+1,a+cnt+1,xx)-a;
e[++m]={get(a[j].id,i),get(i,a[(now+t-2)%cnt+1].id)};
ve[get(a[j].id,i)].emplace_back(get(i,a[(now+t-2)%cnt+1].id));
}
}
for(int i=1;i<=n*n;i++)if(!dfn[i])tarjan(i);
for(int i=1;i<=n*n;i++)co[fr[i]]++,g[fr[i]][(i-1)/n+1]=1;
for(int i=1;i<=n*n;i++)if(co[fr[i]]>1)vis[(i-1)/n+1]=1;
for(int i=1;i<=m;i++)if(fr[e[i].u]!=fr[e[i].v]){
ve2[fr[e[i].v]].emplace_back(fr[e[i].u]),in[fr[e[i].u]]++;
}
for(int i=1;i<=cntt;i++)if(!in[i])qu.push(i);
while(!qu.empty()){
int ft=qu.front();qu.pop();
for(int v:ve2[ft]){
f[v]|=f[ft],f[v]|=g[ft];
if(--in[v]==0)qu.push(v);
}
}
for(int i=1;i<=n*n;i++)if(f[fr[i]][(i-1)/n+1]&&!vis[(i-1)/n+1])vis[(i-1)/n+1]=2;
for(int i=1;i<=n;i++){
if(vis[i]==1)cout<<"G";
else if(vis[i]==2)cout<<"B";
else cout<<"R";
}
return 0;
}