题解:
用Miller-Rabin建边,之后就是个二分图博弈。
这个直接判断最大匹配的必备点即可,注意每个点可以匹配多次,可以用网络流退流来判断。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int RLEN=1<<18|1;
inline char nc() {
static char ibuf[RLEN],*ib,*ob;
(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob) ? -1 : *ib++;
}
template <typename T> inline void rd(T &x) {
char ch=nc(); T i=0,f=1;
while(!isdigit(ch)) {if(ch=='-') f=-1; ch=nc();}
while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
x=i*f;
}
const int N=1e5+50, M=2e6+50, inf=0x3f3f3f3f;
const int pr[]={2,3,5,7,11,13,17,19};
int n,b[N],col[N],vis[N],tar[N],win[N]; LL a[N];
vector <int> e[N];
inline LL mul(LL a,LL b,LL mod) {return (a*b-(LL)((long double)a/mod*b+1e-4)*mod+mod)%mod;}
inline LL power(LL a,LL b,LL mod,LL rs=1) {for(;b;b>>=1,a=mul(a,a,mod)) if(b&1) rs=mul(rs,a,mod); return rs;}
namespace mcmf {
int g[N],nt[M],vt[M],c[M],ec=1;
int lev[N],cur[N],q[N],src,des;
inline void add(int x,int y,int cc) {
nt[++ec]=g[x]; g[x]=ec; vt[ec]=y; c[ec]=cc;
nt[++ec]=g[y]; g[y]=ec; vt[ec]=x; c[ec]=0;
}
inline bool bfs() {
for(int i=1;i<=des;i++) lev[i]=0;
int r; q[r=1]=src; lev[src]=1;
for(int i=1;i<=r;i++) {
int u=q[i];
for(int e=g[u];e;e=nt[e]) if(c[e] && (!lev[vt[e]])) {
lev[vt[e]]=lev[u]+1; q[++r]=vt[e];
if(vt[e]==des) return true;
}
} return false;
}
inline int dinic(int x,int f) {
if(x==des) return f;
int rs=0;
for(int &e=cur[x];e;e=nt[e]) {
if(!c[e] || (lev[vt[e]]!=lev[x]+1)) continue;
int o=dinic(vt[e],min(f-rs,c[e]));
c[e]-=o; c[e^1]+=o; rs+=o;
if(rs==f) return rs;
} return lev[x]=0, rs;
}
inline void maxflow() {
while(bfs()) {
int rs; memcpy(cur+1,g+1,sizeof(int)*des);
while((rs=dinic(src,inf))) memcpy(cur+1,g+1,sizeof(int)*des);
}
}
}
inline void dfs(int x,int c) {
col[x]=c; vis[x]=1;
for(auto v:e[x]) if(!vis[v]) dfs(v,c^1);
}
inline bool MR(LL t) {
if(t==1) return false;
if(t<=3) return true;
if((t%6)!=1 && (t%6)!=5) return false;
LL s1=0, s2=t-1;
while(!(s2&1)) s1++, s2>>=1;
for(int i=0;i<=7;i++) {
if(t==pr[i]) return true;
LL v=power(pr[i],s2,t);
for(int j=1;v!=1 && j<=s1;j++) {
LL v2=mul(v,v,t);
if(v2==1 && (v!=1 && v!=t-1)) return false;
v=v2;
}
if(v!=1) return false;
} return true;
}
inline bool check(LL a,LL b) {
if(a<b) swap(a,b);
if(a%b) return false;
return MR(a/b);
}
int main() {
rd(n);
for(int i=1;i<=n;i++) rd(a[i]), rd(b[i]);
mcmf::src=n+1; mcmf::des=n+2;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(check(a[i],a[j]))
e[i].push_back(j), e[j].push_back(i);
for(int i=1;i<=n;i++) if(!vis[i]) dfs(i,0);
for(int i=1;i<=n;i++) for(auto v:e[i]) if(i<v)
if(col[i]) mcmf::add(v,i,inf);
else mcmf::add(i,v,inf);
for(int i=1;i<=n;i++)
if(col[i]) mcmf::add(i,mcmf::des,b[i]), tar[i]=mcmf::ec-1;
else mcmf::add(mcmf::src,i,b[i]), tar[i]=mcmf::ec-1;
mcmf::maxflow();
for(int i=1;i<=n;i++) if(!mcmf::c[tar[i]]) {
static int q[N],r; r=0;
for(int e=mcmf::g[i];e;e=mcmf::nt[e]) {
int v=mcmf::vt[e];
if(v<=n && mcmf::c[e|1]) q[++r]=tar[v];
}
for(int j=1;j<=r;j++) ++mcmf::c[q[j]];
if(!mcmf::bfs()) win[i]=1;
for(int j=1;j<=r;j++) --mcmf::c[q[j]];
}
LL ans=2e18;
for(int i=1;i<=n;i++) if(!win[i]) ans=min(ans,a[i]);
if(ans!=2e18) printf("Bran %lld\n",ans);
else puts("Tyrion");
}