【UOJ #6】AB题解

#74 破解密码

首先容易得出第i位编号为x的字母的公式:

(26^n -1)*x=26*h[i]-h[i+1]

我们可以先求出(26^n -1)%mod的逆元,乘到右边去即可。

可是,这样做只有50分!

(26^n -1)%mod=0的时候没有逆元!!也就是说这种情况下x为任何数都可以,而这种算法会导致全部输出a,h[]全部都是0了,可能与读入的h不符。

因此这种情况的做法是:求出h[1]用26进制表示的n位数,直接输出就是答案了。因为他满足h[1],后面的必然满足。

<span style="font-size: 18px;">#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <string>
#define LL long long
using namespace std;
LL ni;
int n,mod,ans[100005];
LL Pow(LL x,int nn)
{
	int n=nn;
	LL base=x,ans=1LL;
	while (n)
	{
		if (n&1) ans=ans*base%mod;
		base=base*base%mod;
		n>>=1;
	}
	return ans;
}
void Prepare()
{
	LL x=1;
	for (int i=1;i<=n;i++)
		x=1LL*x*26LL%mod;
	x=(x-1+mod)%mod;
	ni=Pow(x,mod-2);
}
void Solve1()
{
	LL x;
	scanf("%lld",&x);
	for (int i=n;i;i--)
	{
		ans[i]=x%26;
		x/=26;
	}
	for (int i=1;i<=n;i++)
		cout<<(char)(ans[i]+'a');
	cout<<endl;
}
int main()
{
        scanf("%d%d",&n,&mod);
	Prepare();
	if (ni==0LL)
	{
		Solve1();
		return 0;
	}
	LL xx,x,y;
	scanf("%lld",&xx);
	x=xx;
	for (int i=1;i<n;i++)
	{
		scanf("%lld",&y);
		ans[i]=(x*26LL-y+mod)%mod*ni%mod;
		while (ans[i]>26)
			ans[i]-=mod;
		x=y;
	}
	ans[n]=(x*26LL-xx+mod)%mod*ni%mod;
	while (ans[n]>26)
		ans[n]-=mod;
	for (int i=1;i<=n;i++)
		cout<<(char)(ans[i]+'a');
	cout<<endl;
	return 0;
}
</span>

B:

#75 智商锁

基尔霍夫定理+乱搞

基尔霍夫定理可以用O(n^3)时间求出一个无向图的生成树个数。

vfk的基尔霍夫定理证明

说一下这个算法的过程:

1.构造出图对应的矩阵,(i,i)的值是i号点的度数,如果i,j之间连边,那么(i,j)=(j,i)=-1

2.这个图的行列式的值就是生成数个数:

先高斯消元,结果就是对角线的乘积

乱搞的方法是从7号数据延伸出来的:

7号数据的k都是若干个小质数相乘,那么小质数可以直接构造成环,把环用桥连起来的图的生成树个数就是所求了!

乱搞过程及证明见官方题解

<span style="font-size: 18px;">#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstdio>
#include <map>
#define mod 998244353
#define LL long long
using namespace std;
int tot=0,aaa=0,h[1001010],a[1005][15][15],edge[1005];
LL inv[1005],num[1005],d[15][15];
int T;
struct Edge
{
	int x,y,ne,v;
}e[1001010];
void Build(int x)
{
	memset(d,0,sizeof(d));
	for (int i=1;i<12;i++)
		for (int j=i+1;j<=12;j++)
			if (rand()%10>=2)
			{
				a[x][i][j]=a[x][j][i]=1;
				d[i][j]=d[j][i]=mod-1;
				edge[x]++;
				d[i][i]++,d[j][j]++;
			}
}
LL Pow(LL x,int n)
{
	LL ans=1,base=x;
	while (n)
	{
		if (n&1) ans=ans*base%mod;
		base=base*base%mod;
		n>>=1;
	}
	return ans;
}
void Gauss()
{
	int i,j,k;
	for (i=1;i<12;i++)
	{
		for (j=i;j<12;j++)
			if (d[j][i]!=0)
				break;
		for (k=i;k<12;k++)
			swap(d[i][k],d[j][k]);
		LL s=Pow(d[i][i],mod-2);
		for (j=i+1;j<12;j++)
		{
			int rate=(mod-d[j][i]*s%mod)%mod;
			for (k=i;k<12;k++)
				(d[j][k]+=d[i][k]*rate)%=mod;
		}
	}
}
void Hash(int x,int y)
{
	int s=(int)(num[x]*num[y]%mod);
	int k=s%1001001;
	for (int i=h[k];i;i=e[i].ne)
		if (e[i].v==s) return;
	e[++tot].x=x,e[tot].y=y,e[tot].ne=h[k],h[k]=tot,e[tot].v=s;
}
int Get(int x)
{
	int k=x%1001001;
	for (int i=h[k];i;i=e[i].ne)
		if (e[i].v==x) return i;
	return 0;
}
void P(int x,int k)
{
	for (int i=1;i<=12;i++)
		for (int j=i+1;j<=12;j++)
			if (a[x][i][j])
				printf("%d %d\n",k+i,k+j);
}
void Print(int aa,int bb,int cc,int dd)
{
	printf("48 %d\n",edge[aa]+edge[bb]+edge[cc]+edge[dd]+3);
	P(aa,0);
	P(bb,12);
	P(cc,24);
	P(dd,36);
	printf("12 13\n24 25\n36 37\n");
}
int main()
{
        srand(12341234);
        scanf("%d",&T);
	for (int i=1;i<=1000;i++)
	{
		Build(i);
		Gauss();
		num[i]=1;
		for (int j=1;j<12;j++)
			num[i]=num[i]*d[j][j]%mod;
		if (num[i])
			inv[i]=Pow(num[i],mod-2);
	}
	for (int i=1;i<=1000;i++)
		if (num[i])
			for (int j=i;j<=1000;j++)
				if (num[j])
					Hash(i,j);
	while (T--)
	{
		int k;
		scanf("%d",&k);
		if (k==0)
		{
			printf("10 0\n");
			continue;
		}
		int ok=0;
		for (int i=1;i<=1000;i++)
		{
			if (num[i])
				for (int j=i;j<=1000;j++)
					if (num[j])
					{
						LL invv=inv[i]*inv[j]%mod;
						int id=Get((int)((LL)k*invv%mod));
						if (id)
							{ok=1,Print(i,j,e[id].x,e[id].y);break;}
					}
			if (ok) break;
		}
		if (!ok)
			puts("QwQ");
	}
	return 0;
}
</span>

C:

#76 懒癌

只会7号数据的十分:

1.只有一只狗生病:这只狗的主人看到所有狗都没有病,那一定是自己的狗病了。

day+=1,dog+=1

2.有两只狗病了:其中一只病狗的主人一开始认为自己的狗没有病,看到一只狗病了,那么这只狗的主人看不到任何一只狗生病,第一天应该开枪;结果他没有开,说明自己的狗病了,第二天开枪。另一只病狗的主人分析同理。

day+=2,dog+=2

3.有三只狗病了:其中一只病狗的主人认为自己的狗没病,那么对于他所看的两只病狗就面临这2中的处境,可是他在第二天并没有听到枪声,因此一定是自己的狗病了,于是在第三天开枪。其他两只同理。

day+=3,dog+=3

那么最后的答案就是:dog=day=sigma(C(n,i)*i)

感悟:

1.用到逆元一定要考虑逆元是否存在!

2.乱搞好神奇~随机好厉害~

3.假设法,推出矛盾。

时间: 2024-09-28 11:21:51

【UOJ #6】AB题解的相关文章

【codeforces #275(div1)】AB题解

A. Diverse Permutation time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Permutation p is an ordered set of integers p1,???p2,???...,???pn, consisting of n distinct positive integers not larg

【codeforces #282(div 1)】AB题解

A. Treasure time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Malek has recently found a treasure map. While he was looking for a treasure he found a locked door. There was a string s writte

【bestcoder #35】AB题解

DZY Loves Balls Accepts: 371 Submissions: 988 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 一个盒子里有n个黑球和m个白球.现在DZY每次随机从盒子里取走一个球,取了n+m次后,刚好取完.DZY用这种奇怪的方法生成了一个随机的01串S[1?(n+m)].如果DZY第i次取出的球是黑色的,那么S[i]=1,如果是白色的,那么S[

UOJ Round 19 题解

虽然打得的确一般般,但是不知道为什么有心情来写( 开场--这 T3 怎么这么眼熟?然而数据范围这么大-- 写了再说,反正跑不满,说不定卡进去了( 然而不行,5e5 的大样例跑了 0.5s+-- 卡了一会感觉布星,溜了. 开始找 T1 的一堆性质,感觉找到了. 然后要找很多极小环,但是不会. 码了个 T2 的暴力就去搞 T1 的极小环了,以为能有 70,最后连那个说大不大的样例都过不去,一画图发现假了. 这时只剩下 10min,改成 20 分暴力走人了. 丢人 20+20+85=125,rk22,

我说我和人家还让他

http://www.gome.com.cn/search?question=%E6%9D%AD%E5%B7%9E%E6%BB%A8%E6%B1%9F%E8%A5%BF%E5%85%B4%E9%95%87%e6%89%be%e5%b0%8f%e5%a7%90%e4%b8%8a%e9%97%a8%e6%9c%8d%e5%8a%a11858885v7572 http://www.gome.com.cn/search?question=%E6%9D%AD%E5%B7%9E%E6%BB%A8%E6%B1

【题解】A-B

[问题描述]出题是一件痛苦的事情!题目看多了也有审美疲劳,于是我舍弃了大家所熟悉的 A+B Problem,改用 A-B 了哈哈!好吧,题目是这样的:给出一串数以及一个数字 C,要求计算出所有 A-B=C 的数对的个数. (不同位置的数字一样的数对算不同的数对)[输入]第一行包括 2 个非负整数 N 和 C,中间用空格隔开.第二行有 N 个整数,中间用空格隔开,作为要求处理的那串数.[输出]输出一行,表示该串数中包含的所有满足 A-B=C 的数对的个数.[输入输出样例] dec.in      

uoj Goodbye Dingyou Round 题解

2.14 晚上的比赛, 现在改好了四题, 还差提答. 在这补个题解 新年的xor Description 给你 \(n\) , 然后要你构造 \([L, R], L<R\) 使得区间异或和为 \(n\) Solution 做法多的是 我的方法是特判 \(n\le 4\) 的, 然后对于奇数用 \([n-3,n-1]\) , 偶数用 \([n-4, n]\) 新年的叶子 Description 一棵 \(n\le 5e5\) 的树, 每次会随机将一个原树的叶子染黑, 问白点最远距离什么时候变小 S

题解-UOJ 455雪灾与外卖

Problem \(\mathrm{UOJ~455}\) 题意概要:一根数轴上有 \(n\) 只老鼠与 \(m\) 个洞,每个洞有费用与容量限制,要求每只老鼠要进一个洞且每个洞的老鼠不超过自身的容量限制,定义一种方案的费用为所有老鼠移动距离之和加上所有老鼠进的洞费用之和(若一个洞进了 \(k\) 只老鼠,则费用需要计算 \(k\) 次) \(n,m\leq 10^5\) Solution 冬令营时掉线了,只记得这题被大家把好评刷上去了 这题是所谓模拟费用流问题.我理解的模拟费用流其实等价于处理"

UOJ Easy Round #8 T1 打雪仗 题解

题目链接: [UER #8]打雪仗 第一次做通信题,写篇\(blog\)加深印象. 首先分析题目,根据数据,最坏情况下\(m\approx \frac23n\) 刚开始时想着把进制压到更高进制输出,不过实现不来放弃了. 那么把\(2n\)分成一些长度为\(3\)的区间,对于\(1,2\)个字符,直接由小\(B\)告诉小\(A\)是否需要,如果需要则小\(A\)发送字符. 对于第\(3\)个字符,无论需不需要都由小\(A\)发出. 那么显然小\(B\)的输出长度正好为\(\frac23n\). 对