首页 > 其他分享 >[JLOI2015] 有意义的字符串 题解

[JLOI2015] 有意义的字符串 题解

时间:2024-09-27 12:13:18浏览次数:5  
标签:JLOI2015 ch int 题解 矩阵 sqrt dfrac 字符串 dp

拿到题目,我们首先分析一下这个奇怪的式子:

\[\lfloor(\frac{b+\sqrt{d}}{2})^n \rfloor ~\text{mod}~p \]

重点肯定是在里面的那个式子里面,最显眼的肯定也就是那个 \(\sqrt{d}\),根据整体形式,我们可以联系一元二次方程的求根公式 \(x=-\dfrac{-b \pm \sqrt{b^2-4ac}}{2a}\),这里也是一个根号,并且和我们要求的极为相似。于是乎我们尝试着将原式转换成一个方程的根。设原方程为 \(Ax^2+Bx+C=0\),根据对照可以列出方程:

\[\begin{cases} 2A=2\\ -B=b \\B^2-4AC=d \end{cases} \]

解得:

\[\begin{cases} A=1\\ B=-b \\ C=\dfrac{b^2-d}{4} \end{cases} \]

因此原方程转变成了:\(x^2-bx+\dfrac{b^2-d}{4}=0\)。由于每一项的次数呈递减,所以我们考虑移项,看看是否会形成一个转移式子:

\[x^2=bx-\dfrac{b^2-d}{4} \]

这个非常明显,是个标准的转移式子。这个时候就可以想到朴素 DP 大法,按照次数设计状态,然后根据前面的次数进行转移。

但原方程会有两个根,就是 \(\dfrac{b\pm \sqrt{d}}{2}\)。所以直接的转移会包括 \(\dfrac{b-\sqrt{d}}{2}\) 带来的影响值。那么我们需要将 DP 进行合理的定义。设 \(dp_n\) 表示 \((\dfrac{b+\sqrt{d}}{2})^n+(\dfrac{b-\sqrt{d}}{2})^n\) 的值,这个时候我们只需要拿 \(dp_n\) 减去 \((\dfrac{b-\sqrt{d}}{2})^n\) 的影响值就可以了。

轻松写出转移式子:

\[dp_{i}=b\times dp_{i-1}-\dfrac{b^2-d}{4}\times dp_{i-2} \]

但是由于这个次数超出了 int 范围,所以考虑进行优化,这种对极大 \(n\) 的优化,我们不难想到矩阵快速幂优化。我们把转移方程等号右边涉及到的变量提取出来:\(dp_{i-1}\),\(dp_{i-2}\),因此初始矩阵是一个 \(1\times 2\) 的矩阵 ,而对应的常数项就是 \(b\) 和 \(\dfrac{b^2-d}{4}\),所以转移矩阵是一个 \(2\times 2\) 的矩阵。初始矩阵 \(st\) 和转移矩阵 \(a\) 如下:

\[st= \left( \begin{matrix} dp_{i-1} & dp_{i-2} \end{matrix} \right) \]

\[a= \left( \begin{matrix} b & 1 \\ -\dfrac{b^2-d}{4} & 0 \end{matrix} \right) \]

\(st\) 的初始化就是 \(n=1\) 和 \(n=0\) 的情况。

然后我们突然发现一个问题,我们减去的 \((\dfrac{b-\sqrt{d}}{2})^n\) 是一个带根号的式子,我们该如何求出这个向下取整的值呢?

就在一筹莫展之际,那个亮眼的数据范围映入眼帘:\(b^2\leq d<(b+1)^2\)。我们尝试将 \(\sqrt{d}\) 带入进去,\(b\leq \sqrt{d} < b+1\)。所以 \(-1< \dfrac{b-\sqrt{d}}{4}\leq 0\)。

由于 \(|\dfrac{b-\sqrt{d}}{4}|<1\),\(n\) 是个非负整数,所以 \(0\leq |(\dfrac{b-\sqrt{d}}{2})^n|<1\),此时进行分类讨论:

  • 如果 \(b-\sqrt{d}=0\),则 \((\dfrac{b-\sqrt{d}}{2})^n=0\),向下取整为 \(0\)。

  • 如果 \(b-\sqrt{d}<0\),且 \(2\mid n\),此时原式会变成正数,则 \(0<(\dfrac{b-\sqrt{d}}{2})^n<1\),向下取整为 \(0\)。

  • 如果 \(b-\sqrt{d}<0\),且 \(2\nmid n\),此时原式依然是负数,则 \(-1<(\dfrac{b-\sqrt{d}}{2})^n<0\),向下取整为 \(-1\)。

综上所述,\((\dfrac{b-\sqrt{d}}{2})^n\) 的影响值无外乎就是 \(0\) 或者 \(-1\),计算的时候,我们判断第三种情况就可以了。

最后由于模数 \(p=7528443412579576937 \approx 7\times 10^{18}\),计算过程很有可能爆 long long,所以我们可以开一个老祖宗 __int128,写个快读快写,就可以了过了。

代码如下:

#include<bits/stdc++.h>
#define int __int128//懒 
using namespace std;
const int MAXN=83;
const int MOD=7528443412579576937;
int b,d,n;
void read(int &x)
{
	x=0;
	short flag=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-')	flag=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	x*=flag;
}
int quick_mul(int x,int y)//龟速乘,可能没有必要但是就是想写 
{
	int res=0;
	while(y)
	{
		if(y&1)	res=res+x,res%=MOD;
		x=x+x,x%=MOD;
		y>>=1;
	}
	return res;
}
void mul(int f[3],int a[3][3])//转移模板 
{
    int c[3];
    memset(c,0,sizeof(c));
    for(int j=1;j<=2;j++)
    {
        for(int k=1;k<=2;k++)    c[j]=(c[j]+quick_mul(f[k],a[k][j]))%MOD;
    }
    memcpy(f,c,sizeof(c));
}
void mulself(int a[3][3])//矩阵自乘模板 
{
    int c[3][3];
    memset(c,0,sizeof(c));
    for(int i=1;i<=2;i++)
    {
        for(int j=1;j<=2;j++)
        {
            for(int k=1;k<=2;k++)    c[i][j]=(c[i][j]+quick_mul(a[i][k],a[k][j]))%MOD;
        }
    }
    memcpy(a,c,sizeof(c));
}
void write(int x)
{
	if(x<10)
	{
		putchar(x+'0');
		return;
	}
	write(x/10);
	putchar(x%10+'0');
}
signed main()
{
	read(b),read(d),read(n);
	if(!n)//特判 
	{
		puts("1");
		return 0;
	}
	if(n==1)//特判 
	{
		long long B=b,D=d;//玄学调试 
		cout<<((B+sqrt(D)))/2;
		return 0;
	}
	int f[3];
	memset(f,0,sizeof(f));
	int a[3][3];
	memset(a,0,sizeof(a));
	a[1][1]=b,a[1][2]=1,a[2][1]=-(b*b-d)/4;
	f[2]=b,f[1]=(b*b+d)/2;//构造两个矩阵 
	n-=2;
	int temp=n;//n和n-2的奇偶性相同,所以提前储存n-2不会错 
	while(n)//快速幂模板 
	{
		if(n&1)	mul(f,a);
		mulself(a);
		n>>=1;
	}
	if(b*b!=d&&!(temp&1))	f[1]--;//特判第三种情况 
	write(f[1]);//输出 
	return 0;//华丽收场 
}

标签:JLOI2015,ch,int,题解,矩阵,sqrt,dfrac,字符串,dp
From: https://www.cnblogs.com/SuporShoop/p/18435414

相关文章

  • 「KDOI-06-S」消除序列 题解
    分享一个应该很少人想到的做法。首先贪心地想,第一种操作肯定最多选择一次。比如如果选择了下标\(i\)和\(j\)进行第一种操作,那么就等价于在\(\max\{i,j\}\)进行了一次操作。由于代价是非负数,则我们最多只用执行一次。当然也可以不使用这种操作。有了这个思路,我们先考虑不使......
  • 「TAOI-2」Ciallo~(∠・ω< )⌒★ 题解
    手玩了一个小时终于做出来了,这不得写一篇题解记录一下??下面设\(s\)的长度为\(n\),\(t\)的长度为\(m\)。考虑分类讨论:如果\(s\)中有一个子串\(s'\)与\(t\)完全相同(可以用哈希进行比较),设\(s'\)是\(s\)的第\(l\)到第\(r\)个字符组成的字符串,则我们可以删除\([1,......
  • 三星G8 OLED显示器S34BG850SC,使用DP线连接电脑,显示器黑屏问题解决。
    这个问题在网上好像很多人问,但是每个人的情况不同,总之我也是遇到了。事情大概:PC机显卡的DP口通过显示器自带的MiniDP线和显示器相连,这个没什么好说的了,原配只送MiniDP线,想必买这台显示器的人都是先用的这根线。然而我有一台NUC,通过雷电口也连接到了这台显示器。所以我这台G8是......
  • [TJOI2010] 天气预报 题解
    分析一下题目,大致意思就是给定一组常数\(a_i\),然后有一个递推式\(w_i=\sum_{j=1}^{n}w_{i-j}\timesa_{j}\),让你求出\(w_m\)对于\(4147\)取模的值。根据这个\(1\leqm\leq10^7\)的恐怖范围,姑且算到了\(O(m)\)的时间复杂度。但是观察一下这个递推式,发现\(O(m)\)跑......
  • ABC262G 题解
    LISwithStack观察到\(n\le50\),考虑区间dp。设\(dp(l,r,x,y)\)表示区间\([l,r]\)中选出的子序列的最小值\(\gex\),最大值\(\ley\)的方案数。根据栈的性质,设元素\(x\)入栈的时间为\(in_x\),出栈时间为\(out_x\),那么所有元素构成的区间\([in_x,out_x]\)两......
  • 2024-2025专题二题单 - 题解
    A-MoneyinHand(记忆化搜索)原题链接题解B-GoodGraph(并查集)原题链接题解C-IceSkating(dfs求连通块)原题链接题解D-TheLakes(dfs求连通块,连通块内累加,多组数据注意初始化)原题链接题解E-LearningLanguages(建图,dfs统计连通块个数,答案为个数-1)原题链接题......
  • 进击的奶牛题解
    题目描述FarmerJohn建造了一个有 N(2≤N≤105)个隔间的牛棚,这些隔间分布在一条直线上,坐标是 x1,x2,⋯ ,xN​(0≤xi≤109)。他的 C(2≤C≤N)头牛不满于隔间的位置分布,它们为牛棚里其他的牛的存在而愤怒。为了防止牛之间的互相打斗,FarmerJohn想把这些牛安置在指定的隔间,所......
  • 奶牛分厩题解
    题目描述农夫约翰有 N(1≤N≤5000)头奶牛,每头奶牛都有一个唯一的不同于其它奶牛的编号 s[i],所有的奶牛都睡在一个有 K 个厩的谷仓中,厩的编号为 00 到 K−1。每头奶牛都知道自己该睡在哪一个厩中,因为约翰教会了它们做除法,Si mod K的值就是第 i 头奶年所睡的厩的编......
  • 易优cms安全设置常见问题_Eyoucms安全设置问题解决方法
    易优EyouCMS的安全设置对于保护网站免受攻击非常重要。下面列出了一些关于易优CMS安全设置的常见问题及其解决方法:1.目录权限设置为了防止未经授权的访问,应该合理设置网站目录的权限。例如,上传目录通常需要写入权限,而其他目录则应限制权限以防止恶意文件上传或执行。解决方法......
  • 勇攀山丘小队(翻越篇)2——题解
    前言胸有丘壑,气吞山河。正片A题思路其实很简单,当你以当前位置在\(i\),油量为\(p\)的地方开到了位置为\(j\),且\(p_{j+1}-i>p\)时,你肯定走不了了。因此你应当在\(i\)到\(j\)找到能加油最多的加油站来进行加油。需要动态维护这个最大值的数据结构我们可以利用堆来实......