洛谷-P14001 [eJOI 2025] Prison 题解
xiaoniu142857 · · 题解
形式化题意
构造至少
Solution
三元组可以分成如下三类:
- 三个数均相同:形如
\{x,x,x\} 。 - 恰好两个数相同:形如
\{x,x,y\} 。 - 三个数均不同:形如
\{x,y,z\} 。
我们希望 Bob 仅凭接收到的
第
对于第
为了保证边不交,对于每条边
最自然的构造是令三个顶点编号满足:
即
接下来排除退化情况。对于边
因此对于每个点
若
综上,图中无效边数量为
从总边数中减去无效边,剩下的每
个三元组,恰好满足限制。
Code
#include "prison.h"
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i(a);i<b;++i)
#define rept(i,a,b) for(int i(a);i<=b;++i)
using namespace std;
const int MAXM=4305,MAXN=3084000;
struct Tri{int x,y,z;}a[MAXN];
int N;
int c[MAXM][MAXM];
int setup(int M){
memset(c,-1,sizeof(c));
rep(i,0,M){
rep(j,i+1,M){
if(c[i][j]==-1){
int k=(M*2-i-j)%M;
if(k==i||k==j) continue;
c[i][j]=c[i][k]=c[j][k]=c[j][i]=c[k][i]=c[k][j]=N;
a[N]={i,j,k};
++N;
}
}
}
rep(i,0,M){
c[i][i]=N;
a[N]={i,i,i};
++N;
}
return N;
}
vector<int> encode(int A){
return vector<int>({a[A].x,a[A].y,a[A].z});
}
int decode(int X,int Y){
return c[X][Y];
}