五月杂题选做
UOJ#286. 同构判定鸡
大概就是要构造出两个图
这里
有一种可行的构造但是它怎么来的我就不知道了,强正则图是什么东西
因为这个网址太卡了,所以部分原文摘录如下:
可以发现,强正则图不管长啥样,只要参数固定了,它们的特征值就是固定的。
也就是说,一旦我们构造出了两个不同构的强正则图,就解决了这个问题。
事实上,这样的构造存在,且唯一。仅有当 $n = 4$ 时,存在两张不同构的图,均为 $srg \left( 16, 6, 2, 2 \right)$。它们分别是:
$K_4 \times K_4$,即完全图 $K_4$ 与其自身的 Cartesian 积:
Shrikhande graph,构造方法:令 $V = \left\{ 0, 1, 2, 3 \right\} \times \left\{ 0, 1, 2, 3 \right\}$,$S = \left\{ \left( 0, 1 \right), \left( 0, 3 \right), \left( 1, 0 \right), \left( 3, 0 \right), \left( 1, 1 \right), \left( 3, 3 \right) \right\}$,$E = \left\{ \left( (u_1, u_2), (v_1, v_2) \right) \mid \left( u_1, u_2 \right), \left( v_1, v_2 \right) \in V, \left( u_1 - v_1, u_2 - v_2 \right) \in S \right\}$。
以上运算均在环 $\mathbb Z_4$ 下进行。则图 $G = \left( V, E \right)$ 就是 Shrinkhande graph。
容易验证它们都是 $srg \left( 16, 6, 2, 2 \right)$。且它们的邻接矩阵的特征多项式为 $f \left( \lambda \right) = \left( \lambda - 6 \right) \left( \lambda - 2 \right)^6 \left( \lambda + 2 \right)^9$,特征值为一重的 $6$,$6$ 重的 $2$ 和 $9$ 重的 $-2$。
而它们的确是不同构的,因为 $K_4 \times K_4$ 显然有 $K_4$ 作为子图,然而 Shrinkhande graph 没有 $K_4$ 作为子图 (不用找了,真的没有)。
因此,我们只需将 $K_4 \times K_4$ 和 Shrinkhande graph 传给交互库,即可 Hack 掉所有 $6$ 种算法,而 identify() 的过程是非常容易的:只需判断是否有 $K_4$ 作为子图,爆搜即可。
CF582D Number of Binominal Coefficients
数位
考虑
设
复杂度
CF526F Pudding Monsters
把棋盘转成一个排列
由于
单调栈+线段树维护
[CERC2017]Intrinsic Interval
和上一题类似
查询的时候
当然
P4318 完全平方数
首先这个不含平方因子的数满足
显然题目里面的第
那么我们要
通过简单容斥可以发现
然后我们可以直接
考虑一种更优的做法
不过由于并且此题可以分块打表, 所以这种做法的优越性并不能体现出来 所以有没有人出个的加强版啊
复杂度
还有一种
就是筛
真的毒瘤
SP19148 INS14G - Kill them All
考虑把局面看成点
然后我们可以发现
最终走到的终点就是
每个
最后发现式子之间会两两消去
然后预处理阶乘和阶乘逆元就做完了
P6435 「EZEC-1」数列
记
考虑第一项和第二项的差
那么不难得到一个式子
然后开始推式子
记
由于
大概可以这么写
inline LL qpow(LL x,LL y){
x %= P; static LL r; r = 1;
while (y){
if (y&1) r = mul(r,x);
x = mul(x,x),y>>=1;
}
return r;
}
inline LL F(LL a,LL n){
if (n <= 1) return (n*a+1) % P;
if (n&1) return mul((qpow(a,n+1>>1)+1) % P,F(a,n>>1));
return (qpow(a,n) + mul((qpow(a,n>>1)+1) % P,F(a,n-1>>1))) % P;
}
然后就解决了
CF493D Vasya and Chess
以前在
大概是如果
如果
总结但是在博弈论中有巨大的理论价值
CF547D Mike and Fish
对于同一行
还有一种做法
CF576D Flights for Regular Customers
但实际上并不需要这么繁琐
因为人被障碍挡住只可能是障碍覆盖了一条完整的从左
而且这个题甚至可以用
[HEOI2013]Eden 的新背包问题
有两种思路
一种是做前缀背包和后缀背包
或者可以写一个分治背包
这两种做法一种瓶颈是
所以这个题是不是可以用一些其它的方法做到更平衡的复杂度啊
P4256 公主の#19准备月考
观察题面
值域是
不难发现
所以
并且通过
处理完这些信息之后
my solution
P4388 付公主的矩形
不难发现
水水水再水这种简单题要完了啊
P6170 [USACO16FEB]Circular Barn G
大概是个贪心
做一个前缀
不过有一说一
到底是数据水还是卡不满啊
P6091 【模板】原根
补个板子
然后
结合
P5221 Product
推一波式子之后发现需要用到阶乘和
所以阶乘的数组不能开
P6086 【模板】Prufer 序列
继续补板子
做法没啥好说的
const int N = 5000005;
int n,fa[N],p[N],deg[N]; LL ans;
inline void work1(){
register int i; int j;
for (i = 1; i < n; ++i) rd(fa[i]),++deg[fa[i]];
for (i = j = 1; i <= n-2; ++i,++j){
while (deg[j]) ++j; p[i] = fa[j];
while (i <= n-2 && !--deg[p[i]] && p[i] < j) p[i+1] = fa[p[i]],++i;
}
for (i = 1; i <= n-2; ++i) ans ^= 1ll * p[i] * i;
cout << ans << '\n';
}
inline void work2(){
register int i; int j;
for (i = 1; i <= n-2; ++i) rd(p[i]),++deg[p[i]]; p[n-1] = n;
for (i = j = 1; i <= n-1; ++i,++j){
while (deg[j]) ++j; fa[j] = p[i];
while (i <= n-1 && !--deg[p[i]] && p[i] < j) fa[p[i]] = p[i+1],++i;
}
for (i = 1; i <= n-1; ++i) ans ^= 1ll * fa[i] * i;
cout << ans << '\n';
}
int main(){ int Tp; rd(n),rd(Tp); if (Tp == 1) work1(); else work2(); return 0; }
不知为何我交了这么多次还是
P4243 [JSOI2009]等差数列
线段树在差分数组上维护
开一个
大概就是可以搞出递推式
如果
P5299 [PKUWC2018]Slay the Spire
首先因为强化牌的数值一定
P4281 [AHOI2008]紧急集合 / 聚会
练一下欧拉序
大概就是答案一定在
注意写
P2657 [SCOI2009] windy 数
Link:我的数位
数位
P2455 [SDOI2006]线性方程组
补板子
这个题需要我们
注意交换行的时候可能需要和上面的某一行交换
2
0 1 1
0 0 0
如果在消元的时候没有交换
const int N = 55;
int n; db A[N][N];
int main(){
int i,j,k; db v;
cin >> n;
for (i = 1; i <= n; ++i) for (j = 1; j <= n+1; ++j) cin >> A[i][j];
for (i = 1; i <= n; ++i){
if (fabs(A[i][i]) < eps){
for (j = 1; j <= n; ++j) if (j != i && (j > i || fabs(A[j][j]) < eps) && fabs(A[j][i]) > eps){
for (k = 1; k <= n+1; ++k) swap(A[i][k],A[j][k]); break;
}
}
if (fabs(A[i][i]) > eps){
for (j = 1; j <= n; ++j) if (j != i && fabs(A[j][i]) > eps){
v = A[j][i] / A[i][i];
for (k = 1; k <= n+1; ++k) A[j][k] -= A[i][k] * v;
}
}
}
for (i = 1; i <= n; ++i){
if (fabs(A[i][i]) < eps && fabs(A[i][n+1]) > eps){ puts("-1"); return 0; }
}
for (i = 1; i <= n; ++i){
if (fabs(A[i][i]) < eps && fabs(A[i][n+1]) < eps){ puts("0"); return 0; }
}
for (i = 1; i <= n; ++i){
v = A[i][n+1] / A[i][i];
printf("x%d=%.2lf\n",i,v);
}
return 0;
}
P5656 【模板】二元一次不定方程(exgcd)
继续补板子
感觉这个板子的难点好像在
细节还好
就直接
#include <bits/stdc++.h>
#define LL long long
using namespace std;
inline void exgcd(LL a,LL b,LL &d,LL &x,LL &y){
if (!b) d = a,x = 1,y = 0;
else exgcd(b,a%b,d,y,x),y -= (a/b) * x;
}
inline LL Inv(LL a,LL P){
static LL d,x,y; a %= P; exgcd(a,P,d,x,y);
return d == 1 ? (x%P+P)%P : -1;
}
inline LL mul(LL a,LL b,LL p){
static LL an; an = a*b - (LL)((long double)a*b/p) * p;
if (an >= p) an -= p; else if (an < 0) an += p; return an;
}
int n;
inline LL calc(int n,LL *a,LL *b){ //X % b[i] == a[i]
int i;
LL m = 1,ret = 0;
for (i = 1; i <= n; ++i) m *= b[i];
for (i = 1; i <= n; ++i) ret = (ret + mul(a[i],mul(Inv(m/b[i],b[i]),m/b[i],m),m)) % m;
return ret;
}
LL r[15],m[15];
int main(){
cin >> n; for (int i = 1; i <= n; ++i) cin >> m[i] >> r[i];
cout << calc(n,r,m) << '\n';
return 0;
}
/*
input:
2
1000000009 444444
998244353 33412312
output:
19393407174985107
*/
P3301 [SDOI2013]方程
继续补板子
显然这个题可以容斥一下
然后因为模数非质数
所以这题被我当成了扩展卢卡斯模板题(大雾
CF1344D Résumé Review
补
就考虑拉格朗日乘数法的式子
对
然后考虑二分
不过不合法的部分排序后显然是连续的一段
然后求得了实数解
CF512D Fox And Travelling
首先找出所有可能被访问到的点
如果一棵树和不可能访问到的点不相邻
否则根一定是那个和不可能访问到的点相邻已经固定
树和树之间的合并直接乘组合数就可以了
CF986C AND Graph
建
CF1349D Slime and Biscuits
补
这里是xtq的官方题解
式子没啥好说的
我的实现方法是把
复杂度为
不懂为啥有些代码里要求
CF1000F One Occurrence
是在莫队题单里看到的
为了补板子
考虑一个位置
然后按
这个题也可以离线
一个思路类似但更简单的题(只需要BIT)
CF940F Machine Learning
带修莫队板子题
P5906 【模板】回滚莫队&不删除莫队
回滚莫队板子题
这里推荐一个回滚莫队的讲解,包含了只加不减和只减不加这两种情况
首先分块
把同一块的询问按
代码大概像这样
const int N = 200005;
int v[N],lv;
int n,m,a[N],cur[N],ans[N];
int vl[N],vr[N],now;//当前的数组
int cvl[N],cvr[N],cnow;//用于保存信息的数组
inline void Init(){//初始化/清零
memset(vl,0,lv+1<<2),memset(vr,0,lv+1<<2),now = 0;
}
inline void Add(int x,int p){//加入一个点
if (!vl[x]) vl[x] = vr[x] = p;
else vl[x] = min(vl[x],p),vr[x] = max(vr[x],p);
now = max(now,vr[x]-vl[x]);
}
inline void Save(int l,int r){//保存信息
for (int i = l; i <= r; ++i) cvl[a[i]] = vl[a[i]],cvr[a[i]] = vr[a[i]]; cnow = now;
}
inline void Copy(int l,int r){//还原信息
for (int i = l; i <= r; ++i) vl[a[i]] = cvl[a[i]],vr[a[i]] = cvr[a[i]]; now = cnow;
}
int csiz;
struct Ask{
int id,l,r;
bool operator < (const Ask w) const{ return cur[l] != cur[w.l] ? l < w.l : r < w.r; }
}ask[N]; int q;
int main(){
int i,j,l,r;
read(n);
for (i = 1; i <= n; ++i) read(a[i]),v[i] = a[i];
sort(v+1,v+n+1),lv = unique(v+1,v+n+1) - v - 1;
for (i = 1; i <= n; ++i) a[i] = lower_bound(v+1,v+lv+1,a[i])-v-1;
read(m),csiz = m/(1+sqrt(n))+1;
for (i = 1; i <= n; ++i) cur[i] = (i-1)/csiz+1;
for (i = 1; i <= m; ++i){
read(l),read(r);
if (cur[l] == cur[r]){
for (j = l; j <= r; ++j) Add(a[j],j);
ans[i] = now;
Copy(l,r);
}
else{
++q; ask[q].id = i,ask[q].l = l,ask[q].r = r;
}
}
sort(ask+1,ask+q+1);
for (i = j = 1; i <= cur[n] && j <= q; ++i){
if (cur[ask[j].l] != i) continue;
Init(),l = r = i * csiz + 1,Add(a[l],l);
while (j <= q && cur[ask[j].l] == i){
while (r < ask[j].r) ++r,Add(a[r],r);
Save(ask[j].l,l-1);
while (l > ask[j].l) --l,Add(a[l],l);
ans[ask[j].id] = now;
l = i * csiz + 1;
Copy(ask[j].l,l-1);
++j;
}
}
for (i = 1; i <= m; ++i) write(ans[i]),putchar('\n');
return 0;
}
SP744 LPERMUT - Longest Permutation
考虑一个区间合法的条件为
然后考对于每一个
然后区间不能有重复的数值
最后我们把区间翻转一下再做一遍就能解决
CF1198F GCD Groups 2
首先先把所有
每次
先把
可以发现随机了足够多次之后错误率会很低
具体的正确性
考虑整个贪心的过程
不难发现
然后感觉一下这样得到答案的概率貌似挺高的
然后对于
编不下去了,不会证,溜了溜了
SP10707 COT2 - Count on a tree II
树上莫队板子题
AT1219 歴史の研究
只加不减的回滚莫队题
但是
P1758 [NOI2009]管道取珠
考虑题目中给的式子要你求的是什么
也就是枚举两种方案
然后就可以
记
然后滚动数组就解决了
P3802 小魔女帕琪
简单题
不难发现在任意位置发生帕琪七重奏的概率是相等的
AGC044D Guess the Password
交互题
考虑令
首先我们可以通过
然后考虑合并两个
每次合并两个小的即可
最多操作次数
CF639E Bear and Paradox
被搬到了某校内模拟赛
首先考虑怎么求出最优的方案
不难发现如果
那么我们就可以求出
接下来我们考虑那个限制
如果
接下来如果
否则可以解出
然后我们已经求出了所有
然后这个题就可以解决了
根据实现的不同复杂度为
P5572 [CmdOI2019]简单的数论题
莫比乌斯反演
复杂度是
我实现的很丑
P6178 【模板】Matrix-Tree 定理
补板子
AGC044E - Random Pawn
首先不难发现
有
令策略为对于
那么不难得到
令
因此
可以在
然后不难发现策略一定是有若干个点
这个直接用栈贪心一下就好了
评测链接:Link
P6583 回首过去
随便反演可以得到
然后发现可以
CF739E Gosha is hunting
一开始怎么写都过不去
P3690 【模板】Link Cut Tree (动态树)
最简单的
第三个要写
AGC028D - Chords
又被搬到了模拟赛
考虑一个联通块对答案的贡献
记
不难发现
然后记
转移的时候考虑容斥
总方案数可以用
BZOJ2407
考虑枚举第一条边
不过有点难写