原文链接www.cnblogs.com/zhouzhendong/p/UOJ75.html

前言

根本没想到。

题解

首先我们可以考虑一种做法:

找一些图,使得他们各自的生成树个数乘起来等于 k。

那么只要将他们用一条链连起来就得到答案了。

接下来考虑如何得到这些图。

考虑随机生成一个 n 个点的图,它的生成树个数最大是 $n^{n-2}$ 。

我们假装一个 n 个点的图的生成树个数是 $[0,n^{n-2}]$ 中的随机数。

假设我们随机生成了 S 个这样的图,如果我们在这 S 个图中随机选择 t 个连起来,那么我们就得到了 $S^t$ 个随机数。

令 n = 12, S = 1000, t = 4,由于 $n^{n-2} = 12^{10}> 62\cdot 998244353$,所以我们可以在对 998244353 取模之后把生成树个数当作一个 $[0,998244353)$ 中的随机数。则我们得到了 $S^t = 10^{12}$ 个随机数。这 $10^{12}$ 个数中不含有 k 个概率非常小。

我们不可能把所有所有的这些随机数都求出来,所以我们用类似于 BSGS 的办法折半一下就好了。

代码

#pragma GCC optimize("Ofast","inline")
#include <bits/stdc++.h>
#define clr(x) memset(x,0,sizeof (x))
#define For(i,a,b) for (int i=a;i<=b;i++)
#define Fod(i,b,a) for (int i=b;i>=a;i--)
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define fi first
#define se second
#define _SEED_ ('C'+'L'+'Y'+'A'+'K'+'I'+'O'+'I')
#define outval(x) printf(#x" = %d\n",x)
#define outvec(x) printf("vec "#x" = ");for (auto _v : x)printf("%d ",_v);puts("")
#define outtag(x) puts("----------"#x"----------")
#define outarr(a,L,R) printf(#a"[%d...%d] = ",L,R);\
For(_v2,L,R)printf("%d ",a[_v2]);puts("");
using namespace std;
typedef long long LL;
typedef vector <int> vi;
LL read(){
LL x=0,f=0;
char ch=getchar();
while (!isdigit(ch))
f|=ch=='-',ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
const int N=1005,M=20,mod=998244353;
void Add(int &x,int y){
if ((x+=y)>=mod)
x-=mod;
}
void Del(int &x,int y){
if ((x-=y)<0)
x+=mod;
}
int Pow(int x,int y){
int ans=1;
for (;y;y>>=1,x=(LL)x*x%mod)
if (y&1)
ans=(LL)ans*x%mod;
return ans;
}
vector <pair <int,int> > g[N];
int val[N],ival[N];
int calc(int n,vector <pair <int,int> > &e){
static int a[M][M];
clr(a);
for (auto E : e){
int x=E.fi,y=E.se;
a[x][y]++,a[y][x]++;
a[x][x]--,a[y][y]--;
}
For(i,1,n)
For(j,1,n)
if (a[i][j]<0)
a[i][j]+=mod;
n--;
For(i,1,n){
For(j,i,n)
if (a[j][i]!=0){
For(k,i,n)
swap(a[i][k],a[j][k]);
break;
}
if (a[i][i]==0)
return 0;
For(j,i+1,n){
int v=(LL)a[j][i]*Pow(a[i][i],mod-2)%mod;
For(k,i,n)
Del(a[j][k],(LL)a[i][k]*v%mod);
}
}
int ans=mod-1;
For(i,1,n)
ans=(LL)ans*a[i][i]%mod;
return ans;
}
struct hash_map{
static const int Ti=233,mod=1<<20;
int cnt,k[mod+1],v[mod+1],nxt[mod+1],fst[mod+1];
int Hash(int x){
int v=x&(mod-1);
return v==0?mod:v;
}
void clear(){
cnt=0;
memset(fst,0,sizeof fst);
}
void update(int x,int a){
int y=Hash(x);
for (int p=fst[y];p;p=nxt[p])
if (k[p]==x){
v[p]=a;
return;
}
k[++cnt]=x,nxt[cnt]=fst[y],fst[y]=cnt,v[cnt]=a;
return;
}
int find(int x){
int y=Hash(x);
for (int p=fst[y];p;p=nxt[p])
if (k[p]==x)
return v[p];
return 0;
}
int &operator [] (int x){
int y=Hash(x);
for (int p=fst[y];p;p=nxt[p])
if (k[p]==x)
return v[p];
k[++cnt]=x,nxt[cnt]=fst[y],fst[y]=cnt;
return v[cnt]=0;
}
}Map;
int S=1000;
void prework(){
srand(_SEED_);
int n=12;
For(i,1,S){
For(j,1,n)
For(k,1,j-1)
if (rand()%10>=2)
g[i].pb(mp(j,k));
val[i]=calc(n,g[i]);
ival[i]=Pow(val[i],mod-2);
}
Map.clear();
For(i,1,S)
For(j,1,i){
int tmp=(LL)val[i]*val[j]%mod;
Map[tmp]=i*(S+1)+j;
}
}
void solve(int x){
if (!x)
return (void)puts("2 0");
For(i,1,S)
For(j,1,i){
int tmp=(LL)x*ival[i]%mod*ival[j]%mod;
if (Map[tmp]){
int v[4]={i,j,Map[tmp]/(S+1),Map[tmp]%(S+1)};
vector <pair <int,int> > res;
res.clear();
int n=48,cnt=0;
For (k,0,3){
if (cnt>0)
res.pb(mp(cnt,cnt+1));
for (auto e : g[v[k]])
res.pb(mp(e.fi+cnt,e.se+cnt));
cnt+=12;
}
printf("%d %d\n",n,(int)res.size());
for (auto e : res)
printf("%d %d\n",e.fi,e.se);
return;
}
}
}
int main(){
prework();
int T=read();
while (T--)
solve(read());
return 0;
}

  

UOJ#75. 【UR #6】智商锁 随机化算法 矩阵树定理的更多相关文章

  1. 【UOJ#75】【UR #6】智商锁(矩阵树定理,随机)

    [UOJ#75][UR #6]智商锁(矩阵树定理,随机) 题面 UOJ 题解 这种题我哪里做得来啊[惊恐],,, 题解做法:随机\(1000\)个点数为\(12\)的无向图,矩阵树定理算出它的生成树个 ...

  2. UOJ 75 - 【UR #6】智商锁(矩阵树定理+随机+meet-in-the-middle)

    题面传送门 一道很神的矩阵树定理+乱搞的题 %%%%%%%%%%%%%%% vfk yyds u1s1 这种题目我是根本想不出来/kk,大概也就 jgh 这样的随机化带师才能想到出来吧 首先看到生成树 ...

  3. 【构造 meet in middle 随机 矩阵树定理】#75. 【UR #6】智商锁

    没智商了 变式可见:[构造 思维题]7.12道路建设 当你自信满满地把你认为的正确密码输入后,时光机滴滴报警 —— 密码错误.你摊坐在了地上. 黑衣人满意地拍了拍你的肩膀:“小伙子,不错嘛.虽然没解开 ...

  4. UOJ#121. 【NOI2013】向量内积 随机化算法,矩阵

    原文链接www.cnblogs.com/zhouzhendong/UOJ121.html 前言 完蛋了我越来越菜了贺题都不会了. 题解 $O(n ^ 2 d) $ 暴力送 60 分. Bitset 优 ...

  5. 【算法】Matrix - Tree 矩阵树定理 & 题目总结

    最近集中学习了一下矩阵树定理,自己其实还是没有太明白原理(证明)类的东西,但想在这里总结一下应用中的一些细节,矩阵树定理的一些引申等等. 首先,矩阵树定理用于求解一个图上的生成树个数.实现方式是:\( ...

  6. 算法复习——矩阵树定理(spoj104)

    题目: In some countries building highways takes a lot of time... Maybe that's because there are many p ...

  7. POJ 矩阵相乘 (随机化算法-舍伍德(Sherwood))

    周三的算法课,主要讲了随机化算法,介绍了拉斯维加斯算法,简单的理解了为什么要用随机化算法,随机化算法有什么好处. 在处理8皇后问题的时候,穷举法是最费时的,回朔比穷举好点,而当数据量比较大的时候,如1 ...

  8. POJ3318--Matrix Multiplication 随机化算法

    Description You are given three n × n matrices A, B and C. Does the equation A × B = C hold true? In ...

  9. 2018.09.14 codeforces364D(随机化算法)

    传送门 根据国家集训队2014论文集中胡泽聪的随机化算法可以通过这道题. 对于每个数,它有12" role="presentation" style="posi ...

随机推荐

  1. 七.django模型系统(一)

    Ⅰ.django的ORM 1.含义 对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语 ...

  2. elasticsearch-head的安装

    elasticsearch-head是es的一个可视化的客户端插件,可以直接对ES进行增删改查操作,安装前需要先安装NODEJS: 安装: 1.到git上下载源代码: # git clone git: ...

  3. ES6-Babel-Browserify使用教程

    ES6-Babel-Browserify使用教程 定义package.json文件 { "name" : "es6-babel-browserify", &qu ...

  4. window.location.href 传参中文乱码问题!!!

    不是所有地方都会用Ajax  当你使用window.location.href 来传中文参数的时候 如何避免乱码问题 js 是这样写的    下面代码中  方式 封装编码  参数 username  ...

  5. C/C++面试题:编写类String的构造函数、析构函数和赋值函数。

    转https://www.cnblogs.com/alinh/p/9636500.html 考点:构造函数.析构函数和赋值函数的编写方法出现频率:☆☆☆☆☆已知类String的原型为:         ...

  6. Oracle启动操作

    转自:https://www.cnblogs.com/mellowsmile/p/4610942.html 1.启动oracle数据库: 从root切换到oracle用户进入:su - oracle ...

  7. 前端面试题整理—Node篇

    1.node有哪些特征,与其他服务器端对比 特征:单线程.事件驱动.非阻塞I/O node 无法直接渲染静态页面,提供静态服务 node 没有根目录的概念 node 必须通过路由程序指定文件才能渲染文 ...

  8. [Android] Android 支持下拉刷新、上拉加载更多 的 XRecyclerview

    XRecyclerView一个实现了下拉刷新,滚动到底部加载更多以及添加header功能的的RecyclerView.使用方式和RecyclerView完全一致,不需要额外的layout,不需要写特殊 ...

  9. [转载]再谈PostgreSQL的膨胀和vacuum机制及最佳实践

    本文转载自 www.postgres.cn 下的文章: 再谈PostgreSQL的膨胀和vacuum机制及最佳实践http://www.postgres.cn/news/viewone/1/390 还 ...

  10. SQL数字型注入代码审计

    数字型注入 SQL注入攻击,简称注入攻击,是发生于应用程序与数据库层的安全漏洞. 简而言之,是在输入的字符串之中注入sql指定,在设计不良的程序当中忽略了检查,那么这些注入进去的指令就会被数据库服务器 ...