ARC166

ARC166

前言

到了 e 难度莫名陡增.......

[ARC166A] Replace C or Swap AB

一个比较简单的贪心

进行交换操作肯定会减少 C 的个数。并且唯一可以变序位置的操作是操作三,所以最后结果一定是 B 尽可能在前。等价于把某个 A 向后移一个位置。贪心地把靠前的 C 都替换成 A。判断当前 X 中是否每个对应的 A 所在位置都不大于它在 Y 中的目标位置即可。

signed main() 
{
    int T;
    cin >> T;
  
    while (T--) 
	{
        int n; string x, y;
        cin >> n >> x >> y;
        deque<int> q;
        bool flag = 0;

        for (rint i = 0; i < n; i++) 
		{
            if (y[i] == 'C') 
			{
                if (x[i] != 'C') 
				{
                    puts("No");
                    flag = 1;
                    break;
                } 
				else q.push_back((int)i);
            }
        }

        if (flag) continue;
        int cnt = 0;
        q.push_back(n);

        while (!q.empty()) 
		{
            int a = q.front();
            q.pop_front();
            int a1 = 0, c1 = 0;

            for (rint i = cnt; i < a; i++) 
			{
                if (x[i] == 'A') a1++;
                if (x[i] == 'C') c1++;
                if (y[i] == 'A') 
				{
                    if (!a1 && !c1) 
					{
                        puts("No");
                        flag = 1;
                        break;
                    }
                    if (!a1) c1--;
                    else a1--;
                }
            }
            if (flag) break;
            if (a1 > 0) 
			{
                puts("No");
                flag = 1;
                break;
            }
            cnt = a + 1;
        }
        if (flag) continue;
        puts("Yes");
    }

    return 0;
}

[ARC166B] Make Multiples

传送门link

直接 dp,其实可以不用状态压缩 dp

\(f[i][0/1][0/1][0/1]\) 表示前 \(i\) 个数是否有 \(a,b,c\) 的倍数

预处理出来每个数变成某个数的倍数要加上多少然后直接转移

int lcm(int a, int b) {return a * b / __gcd(a, b);}

signed main() 
{
    cin >> n >> x >> y >> z;

    for (rint i = 1; i <= n; i++) 
	{
        int t;
		cin >> t;
        a[i] = x - (t - 1) % x - 1;
        b[i] = y - (t - 1) % y - 1;
        c[i] = z - (t - 1) % z - 1;
        ab[i] = lcm(x, y) - (t - 1) % lcm(x, y) - 1;
        bc[i] = lcm(z, y) - (t - 1) % lcm(z, y) - 1;
        ac[i] = lcm(x, z) - (t - 1) % lcm(x, z) - 1;
        abc[i] = lcm(lcm(x, y), z) - (t - 1) % lcm(lcm(x, y), z) - 1;
    }

    memset(f, 0x3f, sizeof f);
    f[0][0][0][0] = 0;

    for (rint i = 1; i <= n; i++) 
	{
        f[i][0][0][0] = f[i - 1][0][0][0];
        
        f[i][0][0][1] = min(f[i - 1][0][0][1], f[i - 1][0][0][0] + c[i]);
        f[i][0][1][0] = min(f[i - 1][0][1][0], f[i - 1][0][0][0] + b[i]);
        f[i][1][0][0] = min(f[i - 1][1][0][0], f[i - 1][0][0][0] + a[i]);
        
        f[i][0][1][1] = min({f[i - 1][0][1][1], f[i - 1][0][0][1] + b[i], f[i - 1][0][1][0] + c[i], f[i - 1][0][0][0] + bc[i]});
        f[i][1][0][1] = min({f[i - 1][1][0][1], f[i - 1][0][0][1] + a[i], f[i - 1][1][0][0] + c[i], f[i - 1][0][0][0] + ac[i]});
        f[i][1][1][0] = min({f[i - 1][1][1][0], f[i - 1][1][0][0] + b[i], f[i - 1][0][1][0] + a[i], f[i - 1][0][0][0] + ab[i]});
        
		f[i][1][1][1] = min({f[i - 1][1][1][1], f[i - 1][1][1][0] + c[i], f[i - 1][1][0][1] + b[i], f[i - 1][0][1][1] + a[i], f[i - 1][0][0][1] + ab[i], f[i - 1][0][1][0] + ac[i], f[i - 1][1][0][0] + bc[i], f[i - 1][0][0][0] + abc[i]});
    }

    cout << f[n][1][1][1] << endl;
    
    return 0;
}

[ARC166C] LU / RD Marking

传送门link

将边转化成点的问题,染色就是染 \((i,j)\)\((i+1,j-1)\) 位置的点

将点连边。因为染色方式只有一种,所以这个点阵构成了若干条互不相关的斜向的链。

答案是这些链的方案的乘积。

考虑一条边数为 \(n\) 的链。限制为相邻的边不能同时选。

\(f_i\) 表示前 \(i\) 条边的方案,因为第 \(i\) 条边若不选,则方案为 \(f_{i-1}\),第 \(i-1\) 条边选不选都无所谓,\(f_i=f_{i-1}+f_{i-2}\)。若第 \(i\) 条边选,则第 \(i-1\) 条边一定不能选,所以从 \(f_{i-2}\) 转移过来。初始态为 \(f_0=1,f_1=2\)(即斐波那契数列)

一个矩形切割出的若干条链的边数是形如 \(1,3,5,7,8,8,8,8,7,5,3,1\) 这样的。对于左右两边可以求一个 \(f\) 序列奇数位的前缀积,中间部分就快速幂。

复杂度 \(O(n+T\log n)\)

signed main()
{
	f[0] = 1;
	f[1] = s[1] = 2;
	for (rint i = 2; i < N; i++) f[i] = (f[i - 1] + f[i - 2]) % mod;
	for (rint i = 3; i < N; i++)
	{
		if (!i % 2) continue;
		s[i] = s[i - 2] * f[i] % mod;
	}
	cin >> T;
	while (T--)
	{
		cin >> n >> m;
		if (n > m) swap(n, m);
		cout << s[2 * n - 1] * s[2 * n - 1] % mod * qpow(f[2 * n], m - n) % mod << endl;
	}
	return 0;
}

[ARC166D] Interval Counts

传送门link

假设当前已经满足了 \(1\sim i-1\) 的限制,维护一个队列表示当前还没确定右端点的所有左端点。

如果 \(y_i=y_{i-1}\),让原来右端点接在 \(x_{i-1}\) 的区间接到 \(x_i\)

如果 \(y_i>y_{i-1}\),原来的区间就算全部接到 \(x_i\) 上仍然不够,需要再加 \(y_i-y_{i-1}\) 个左端点为 \(x_{i-1}+1\) 的区间。

如果 \(y_i<y_{i-1}\),说明要删掉 \(y_{i-1}-y_i\) 个区间,由于要让最小值最大,所以需要删掉左端点最小的区间。

于是只维护一个左端点递增的区间,区间数很多,记录这个左端点的个数。

复杂度 \(O(n)\)

int n;
int x[N], y[N];
int ans = inf;
struct node
{
	int x, y;
}q[N];

signed main() 
{
	cin >> n;
	for (rint i = 1; i <= n; i++) cin >> x[i];
	for (rint i = 1; i <= n; i++) cin >> y[i];
	
	x[0] = -inf;
	int head = 1, top = 0;
	
	for (rint i = 1; i <= n; i++) 
	{
		if (y[i] > y[i - 1]) 
		{
			q[++top] = {x[i - 1] + 1, y[i] - y[i - 1]};
		} 
		if (y[i] < y[i - 1]) 
		{
			int delta = y[i - 1] - y[i];
			while(delta && head <= top)
			{
				int w = min(q[head].y, delta);
				delta -= w;
				q[head].y -= w;
				ans = min(ans, x[i] - 1 - q[head].x);
				if (!q[head].y) head++;
				else break;
			}
		}
	}
	
	if (ans >= inf) cout << -1 << endl;
	else cout << ans << endl;
	
	return 0;
}

[ARC166E] Fizz Buzz Difference

传送门link

在解决这个题目之前,需要学习一个东西。

如何求解线性同余不等式。

给定 \(l,r,a,m(l,r,a\in[0,m),l\le r)\),求最小非负整数 \(x\) 满足:\( l\le ax \bmod m \le r \)

尝试将问题转化为一个更小规模的问题 \(l \le ax-km \le r\)

其中 \(k=\lfloor\frac{ax}{m}\rfloor\)

如果在 \([l,r]\) 之间找到一个 \(a\) 的倍数,即 \(\lfloor\frac{r}{a}\rfloor a\ge l\),这意味着 \(k\) 可以取到最小值 \(0\)。同时,我们直接找到 \(x\) 的一个解:\(\lceil\frac{l}{a}\rceil\)

关于此解的最小性,只看左侧不等式,我们有 \(x\) 是合法解的必要条件 \(ax\ge l+km\),即 \(x\ge\lceil\frac{mk+l}{a}\rceil\),显然此下界关于 \(k\) 是单调递增的,而此解恰好取到了最小下界,故一定是最小的可能合法解,而其合法性显然。

否则,将上式进一步整理为 \(ax-r \le km\le ax-l\)

由于 \([l,r]\) 之间没有 \(a\) 的倍数,设 \(l=pa+u,r=pa+v\),有:\( a(x-p)-v\le km \le a(x-p)-u \)

上式对 \(a\) 取模可得:\(-r \bmod a \le km \bmod a \le -l \bmod a\)

尝试说明当找到该式中 \(k\) 的最小可行解时就能唯一确定 \(x\) 的最小可行解。首先一个原式中可行的 \(x\) 一定对应一个该式中可行的 \(k\),并且对应关系是单调的,即更小的 \(x\) 对应于不会更大的 \(k\),因此我们找到的最小可行 \(k\le\) 最小可行 \(x\) 对应的 \(k\)。同时,对于一个满足上式的 \(k_0\),容易验证一定有 \(x_0=\lfloor\frac{km+r}{a}\rfloor\) 是原式的可行解,且恰好取到下界。

问题转化为求解 \(k\),即 \((-r \bmod a , -l \bmod a,m \bmod a,a)\) 的新问题,问题规模减小,不断递归调用

Code:

int solve(int l, int r, int a, int m) 
{
	if (l > r || !a) return -1;
	if (!l) return 0;
	if (r / a * a >= l) return (l - 1) / a + 1;
	int k = solve((a - r % a) % a, (a - l % a) % a, m % a, a);
	return k == -1 ? -1 : (m * k + l - 1) / a + 1;
}

现在再来处理这道题目。

假设现在这个合法区间是 \([L_0,R_0]\),将 \(R_0\) 不断 \(-1\) 得到一系列区间,它们的 \(n_a-n_b\) 取值一定恰好覆盖 \([1,n]\)。因此 \(n\)\([1,n]\) 中限制最严格的,将题目限制修改为 \(n_a-n_b\le n\)

合法区间一定满足 \(a\mid L-1,a\mid R+1\),否则可以将端点外移让区间长度变长且 \(n_a-n_b\) 不会变大。设 \(L=ak_1+1,R=ak_2-1(k_1<k_2)\),首先来最大化 \(R-L\),即最大化 \(x=k_2-k_1\)

确定 \(x\) 后,\(n_a=x-1\),因此需最大化 \(n_b\)

一旦确定区间中第一个 \(b\) 的倍数的位置 \(pos\),那么 \(n_b\) 也唯一确定,故只需要最小化 \(pos-L\)

\(g=\gcd(a,b)\),那么 \(pos-L\) 最小能恰好取到 \(g-1\)。因此,确定 \(x\) 后可以直接求得最小可能 \(n_a-n_b\),且此值关于 \(x\) 具有单调性。二分即可。

记求得的最大 \(x\)\(X\),此时区间内至少需要出现 \(c=X-1-n\)\(b\) 的倍数。此限制可以表示为 \(R-L-R\bmod b\ge b(c-1)\),即 \((L+aX-2)\bmod b\in[0, aX-2-b(c-1)]\),如果 \(aX-2-b(c-1)\ge b\),这意味着这条限制不存在,直接令 \(L=1\);否则问题可以转化成 \(ak_1\bmod b\ge (1-aX)\bmod b\),求最小合法 \(k_1\)。刚才上面那个代码就可以快速解决。

复杂度 \(O(T\log V)\)


int solve(int l, int r, int a, int m) 
{
	if (l > r || !a) return -1;
	if (!l) return 0;
	if (r / a * a >= l) return (l - 1) / a + 1;
	int k = solve((a - r % a) % a, (a - l % a) % a, m % a, a);
	return k == -1 ? -1 : (m * k + l - 1) / a + 1;
}

signed main() 
{
	int T;
	cin >> T;
	while (T--) 
	{
		cin >> n >> a >> b;
		int g = __gcd(a, b);
		int l = 1, r = inf, res;
		while (l < r) 
		{
			int mid = (l + r) >> 1;
			if (mid - 2 - (a * mid - 1 - g) / b > n) r = mid;
			else l = mid + 1, res = mid;
		}
		int tmp = solve(((1 - a * res) % b + b) % b, b - 1, a, b);
		cout << tmp * a + 1 << " " << (tmp + res) * a - 1 << endl;
	}
	return 0;
}

[ARC166F] Tangent Addition Formula

传送门link

一道不可做的题,看的第一篇题解。懂了但没有完全懂。。。。

\(t\) 的性质二 \(\forall x,y\in \mathbb{N},t(x+y)(1-t(x)t(y))\equiv t(x)+t(y)\pmod p\) 目前没法入手解决,记标记为式 \((\star)\)

带入 \(x=0,y=0\),得到 \(t(0)(1-t(0)^2)\equiv 2t(0)\pmod p\),解得 \(t(0)=0\)\(t(0)^2\equiv -1\pmod p\)。设 \(I^2\equiv-1\pmod p\),即模 \(p\) 意义下虚数单位,则 \(t(0)\in\{I,-I,0\}\)

\(t=(0,0,0,\cdots)\) 满足 \((\star)\),说明 \(b=0\)\(t\) 存在。

由和角公式 \(\tan(x+y)=\dfrac{\tan(x)+\tan(y)}{1-\tan(x)\tan(y)}\),对比 \((\star)\),对比可得移了项少了取模。\(t(x)\) 就是某种模意义下的正切函数。

首先展开 \(\tan(x)=\dfrac{\sin(x)}{\cos(x)}\)

根据欧拉公式 \(e^{ix}=\cos(x)+i\sin(x)\),得到 \(\sin(x)=\dfrac{e^{ix}-e^{-ix}}{2i},\cos(x)=\dfrac{e^{ix}+e^{-ix}}{2}\)

相除得到 \(\tan(x)=\dfrac{1-(e^{2i})^{x}}{1+(e^{2i})^{x}}\times i\)

形式上 \(\tan(x)\) 形如 \(\dfrac{1-r^{x}}{1+r^{x}}\cdot i\)

【结论 1】

\(t(x)\) 形如 \(\dfrac{1-r^{x}}{1+r^{x}}\cdot I\),其中 \(I^2\equiv -1\pmod p\)

证明:将该式带入 \((\star)\),得到:

\(t(x+y)(1-t(x)t(y)) = \dfrac{1-r^{x+y}}{1+r^{x+y}}\cdot I\cdot(1-\dfrac{1-r^{x}}{1+r^{x}}\cdot I\cdot\dfrac{1-r^{y}}{1+r^{y}}\cdot I)\)

利用 \(I^2\equiv -1\pmod p\),得到 \(\equiv\dfrac{1-r^{x+y}}{1+r^{x+y}}\cdot I\cdot(1+\dfrac{(1-r^x)(1-r^y)}{(1+r^x)(1+r^y)})\pmod p\)

将分子分母去括号并通分,得到 \(\equiv\dfrac{1-r^{x+y}}{1+r^{x+y}}\cdot I\cdot\dfrac{2(1+r^{x+y})}{1+r^x+r^y+r^{x+y}}\pmod p\)

约分,分解因式,得 \(\equiv I\cdot\dfrac{(1+r^x)(1-r^y)+(1-r^x)(1+r^y)}{(1+r^x)(1+r^y)}\pmod p\)

拆开分子,得 \(\equiv \dfrac{1-r^y}{1+r^y}\cdot I+\dfrac{1-r^x}{1+r^x}\cdot I\pmod p\)

再代回去 \(\equiv t(x)+t(y)\pmod p\)

左边同余于右边,\((\star)\) 成立。原命题得证。

上面除了 \(I^2\equiv -1\pmod p\) 都是恒等变换,因此原问题变成了和 \(I\) 相关的问题。而这个式子,就是二次剩余。

暂记模 \(p\) 意义下的整数域为 \(\mathbb{Z}_p\)

讨论 \(p=2\)

\(b=0\),则可以有 \(t=(0,0,0,\cdots)\) 满足 \((\star)\)

\(b=1\),则可以有 \(t=(1,1,1,\cdots)\) 满足 \((\star)\)

由于这两种数列的取值和项数无关,对于所有 \(a\) 都能这样取

因此,此时 \(t\) 存在。

讨论 \(p\equiv 1\pmod 4\)

【结论 2】

\(p\equiv 1\pmod 4\Leftrightarrow \exists I\in\mathbb{Z}_p,I^2\equiv-1\pmod p\),其中 \(p\) 为奇质数。

证明:

\(p\) 的最小正原根为 \(g\)。由原根存在性定理,\(g\) 存在。

\(g^{p-1}\equiv 1\pmod p\)\(g\) 可视为 \(\mathbb{Z}_p\)\(p-1\) 次单位根。由 \(I^4\equiv 1\pmod p\)\(I\) 可视为 \(\mathbb{Z}_p\)\(4\) 次单位根。

因此有 \(I=g^{\frac {p-1} 4}\)。若 \(I\) 存在,则 \(\dfrac {p-1} 4\in\mathbb{Z}\),即 \(4|p-1\)

故若 \(I\) 存在,则 \(p\equiv 1\pmod 4\),必要性得证。

对于充分性,取 \(I\equiv g^{\frac {p-1} 4}\pmod p\),满足题意。

原命题得证。

既然如此,再结合上 \(t(0)\in\{I,-I,0\}\),我们继续分类。

接下来。所有结论都有前提条件 \(p\equiv 1\pmod 4\)

讨论 \(t(1)\in\{I,-I\}\)

【结论 3】

\(t(1)\in\{I,-I\}\),则 \(\forall x\in\mathbb{N^+},t(x)=t(1)\)

数学归纳法,当 \(x=1\) 时显然相等。

现在假设当 \(x=n\in\mathbb{N^+}\) 时成立,即 \(t(n)=t(1)\),下证当 \(x=n+1\) 时成立。

\(t(n+1)(1-t(n)t(1))\equiv t(n)+t(1)\pmod p\)

代入 \(t(n)=t(1)\),得 \(t(n+1)(1-t(1)^2)\equiv 2t(1)\pmod p\)

代入 \(t(1)^2\equiv -1\pmod p\),两边同时除以 \(2\),得到 \(t(n+1)=t(1)\)

原命题得证

由此可得,本类的合法 \(t\) 有且仅有六种情况

\(t=(I,I,I,I,\cdots)\)

\(t=(I,-I,-I,-I,\cdots)\)

\(t=(0,I,I,I,\cdots)\)

\(t=(0,-I,-I,-I,\cdots)\)

\(t=(-I,I,I,I,\cdots)\)

\(t=(-I,-I,-I,-I,\cdots)\)

讨论 \(t(1)\notin\{I,-I\}\)

【结论 4】

\(t(1)\notin\{I,-I\}\),则 \(t(0)=0\)

证明:考虑证明其逆否命题,即若 \(t(0)\neq 0\),则 \(t(1)\in\{I,-I\}\)

\(x=0,y=1\) 代入 \((\star)\),得到 \(t(1)(1-t(1)t(0))\equiv t(1)+t(0)\pmod p\)

化简得到 \((t(1)^2+1)t(0)\equiv 0\pmod p\)

因为 \(t(0)\neq 0\),两边同时除以 \(t(0)\),移项得 \(t(1)^2\equiv -1\pmod p\)

解得 \(t(1)\in\{I,-I\}\)

原命题得证

将特值代入 \((\star)\) 也起不了效果了,只能求助结论 1 了

由于分母不能为 \(0\),所以要求 \(\forall x\in\mathbb{N},r^x\not \equiv-1\pmod p\)。如果存在 \(r\in\mathbb{Z}_p\),则 \(t\) 存在,否则 \(t\) 不存在

由性质三:\(t(a)=b\)。列方程 \(b\equiv \dfrac{1-r^a}{1+r^a}\cdot I\pmod p\)

化简得到 \(r^a\equiv \dfrac{I-b}{I+b}\pmod p\),是个模为质数的高次剩余方程,原根加 BSGS 就能解

在本分类下,\(t\) 存在当且仅当存在 \(r\in\{r|r^a\equiv \dfrac{I-b}{I+b}\pmod p\}\) 使得 \(\forall x\in\mathbb{N},r^x\not\equiv -1\pmod p\)

讨论 \(p\equiv 3\pmod 4\)

在普通的模意义下整数域上没有

但是高斯整环 \(\mathbb{Z}(i)\) ???

不妨记模 \(p\) 意义下高斯整环为 \(\mathbb{Z}(i)_p=\{a+bi|a,b\in\mathbb{Z}_p\}\),不难得出这玩意是个有限域。

在强行添加上虚数单位后,讨论 \(t\) 的存在条件。

由于对于所有 \(x\in\mathbb{Z}_p\) 可以看作 \(x+0\cdot i\in\mathbb{Z}(i)_p\),因此 \(\mathbb{Z}_p\subseteq\mathbb{Z}(i)_p\)

依题有 \(t(x)=\dfrac{1-r^x}{1+r^x}\cdot i\in\mathbb{Z}_p\),因此 \(r\in\mathbb{Z}(i)_p\) 应该满足 \(\forall x\in\mathbb{N},\dfrac{1-r^x}{1+r^x}\cdot i\in\mathbb{Z}_p\)\(r^x\not\equiv -1\pmod p\)

判断属不属于集合还是太麻烦了。能不能转化一下?当然可以。我们有如下结论:

【结论 5】

\(\forall x\in\mathbb{N},\dfrac{1-r^x}{1+r^x}\cdot i\in\mathbb{Z}_p\Leftrightarrow r^{p+1}\equiv1\pmod p\)

证明:根据二项式定理有 \((x+y)^p\equiv x^p+y^p\pmod p\)。(仅有 \(\dbinom{p}{0}\)\(\dbinom{p}{p}\) 不能被 \(p\) 整除,其余均含因数 \(p\)。)

\(z=x+yi\in\mathbb{Z}_p\),则 \(z^p\equiv x^p+(yi)^p\pmod p\)

由于 \(p\equiv 3\pmod 4\),有 \(i^p=-i\),因此 \(z^p\equiv x^p-y^pi\pmod p\)

根据费马小定理,\(x^p\equiv x\pmod p\),所以 \(z^p\equiv x-yi\pmod p\)

当且仅当 \(y=0\),即 \(z\in\mathbb{Z}_p\) 时,\(z=x-yi\)

\(z\in\mathbb{Z}_p\Leftrightarrow z^p\equiv z\pmod p\)

代入 \(z=\dfrac{1-r^x}{1+r^x}\cdot i\),原命题可转化为
\((\dfrac{1-r^x}{1+r^x}\cdot i)^p\equiv\dfrac{1-r^x}{1+r^x}\cdot i\pmod p\Leftrightarrow r^{p+1}\equiv1\pmod p\)

移项有 \((\dfrac{1-r^x}{1+r^x}\cdot i)^p-\dfrac{1-r^x}{1+r^x}\cdot i\equiv 0\pmod p\)

拆括号,得到 \(-\dfrac{(1-r^x)^p}{(1+r^x)^p}\cdot i-\dfrac{1-r^x}{1+r^x}\cdot i\equiv 0\pmod p\)

两边同乘 \(-\dfrac 1 i\),得:\(\dfrac{(1-r^x)^p}{(1+r^x)^p}+\dfrac{1-r^x}{1+r^x}\equiv 0\pmod p\)

用上面二项式定理的推论展开幂次,得 \(\dfrac{1-r^{xp}}{1+r^{x^p}}+\dfrac{1-r^x}{1+r^x}\equiv 0\pmod p\)

通分,得 \(\dfrac{1-(r^{p+1})^x}{1+r^x+r^{px}+r^{(p+1)x}}\equiv 0\pmod p\)

去分母,移项,得 \((r^{p+1})^x\equiv 1\pmod p\)

由于该式对于所有 \(x\) 均成立,可以去掉指数,得 \(r^{p+1}\equiv 1\pmod p\)

充分性得证。以上各式均为恒等变换,反过来可证明必要性 原命题得证。

和上面同样解方程 \(b\equiv \dfrac{1-r^a}{1+r^a}\cdot i\pmod p\),解得 \(r^a\equiv \dfrac{i-b}{i+b}\pmod p\)

不知道原根存在性,没办法 BSGS

\(\mathbb{Z}(i)_p\) 是个有限域吗

这个域共有 \(p^2\) 个元素,根据有限域的存在性和唯一性,其为有限域 \(\mathbb{F}_{p^2}\)

【结论 6】

(有限域原根存在性)
有限域 \(\mathbb{F}\) 存在元素 \(g\) 使得 \(g^n=1,\mathbb{F}=\{g^t|0\le t<n\}\)

综合上述讨论,我们最终得到 \(t\) 的存在性判定方式

\(p=2\)\(b=0\)\(b^2\equiv -1\pmod p\) 时,\(t\) 存在

否则,若 \(t\) 存在,则存在 \(r\) 满足以下三个条件

\(r^a\equiv u\pmod p\)

\(r^v\equiv 1\pmod p\)

\(\forall x\in\mathbb{N},r^x\not\equiv-1\pmod p\)

其中 \(u=\dfrac{i-b}{i+b},i^2\equiv-1\pmod p,v=\left\{\begin{matrix} 0 &amp; (p\equiv 1\pmod 4)\\ p+1 &amp; (p\equiv 3\pmod 4) \end{matrix}\right.\)

记循环群大小 \(n=\left\{\begin{matrix} p-1 &amp; (p\equiv 1\pmod 4)\\ p^2-1 &amp; (p\equiv 3\pmod 4) \end{matrix}\right.\)

\(r\equiv g^t\pmod p\),则 \(r^v\equiv g^{tv}\equiv 1\pmod p\)

\(g^n\equiv 1\pmod p\),得到 \(n|tv\),因此有 \(\dfrac n {\gcd(n,v)}|t\)

同理,由 \(r^x\not\equiv-1\pmod p\)\(g^{2tx}\not\equiv1\pmod p\)

因此 \(tx\not\equiv\dfrac n 2\pmod n\)。这玩意可以继续除下去直到 \(n\) 中的 \(2\) 因数被除干净

\(2^m|n,2^{m+1}\nmid n\),则可以推出 \(2^m|t\)

所以 \(t\) 的一个取值是 \(\operatorname{lcm}(\dfrac n {\gcd(n,v)},2^m)\)

不妨就令 \(t\) 为该值。则再设 \(r\equiv g^{tk}\)

还差条件一,代入 \(r\)\(g^{atk}\equiv u\)

再和上面一样的做法,得出 \(u^{\frac{n}{\operatorname{gcd}(at, n)}}=1\)

复杂度 \(O(T\log p)\)

int qpow(int a, int b)
{
	int res = 1;
	while (b)
	{
		if (b & 1) res = res * a % p;
		b >>= 1;
		a = a * a % p;
	}
	return res;
}

struct complex 
{
	int X, Y;
	bool operator == (complex x) {return X == x.X && Y == x.Y;}
	complex operator * (complex x)
	{
		complex s;
		s = (complex) {X * x.X % p + imod * x.Y % p * Y % p, Y * x.X % p + X * x.Y % p};
		if (s.X >= p) s.X -= p; 
		if (s.Y >= p) s.Y -= p;
		return s;
	}
	complex operator ^ (int b) 
	{
		complex s({1, 0}), a(*this);
		while (b) {if(b & 1) s = s * a;a = a * a;b >>= 1;}
		return s;
	}
};

signed main() 
{
	cin >> T;
	while (T--)
	{
		cin >> p >> a >> b;
		
		if (p == 2 || b == 0 || b * b % p + 1 == p) 
		{
			puts("Yes");
			continue;
		}
		
		if ((p & 3) == 1) 
		{
			n = p - 1;
			int f, l;
			
			do 
			{
				l = rand() % p;
				imod = l * l % p - (p - 1);
				imod < 0 && (imod += p);
			} 
			
			while (!l || qpow(imod, (p - 1) >> 1) == 1);
			f = ((complex) {l, 1} ^ ((p + 1) >> 1)).X;
			if (p - f < f) f = p - f;
			int t = n / (n & (-n));
			t /= __gcd(a, t);
			
			int u = (f - b) * qpow(f + b, p - 2) % p;
			if (u < 0) u += p;
			if (qpow(u, t) == 1) puts("Yes");
			else puts("No");
		} 
		
		else 
		{
			n = p * p - 1;
			imod = p - 1;
			
			int t = n / ((n & (-n)) / __gcd((n & (-n)), p - 1) * (p - 1));
			t /= __gcd(a, t);
			int inv = qpow(b * b % p + 1, p - 2);
			complex u = {(1 - b * b % p + p) * inv % p,  (b << 1) % p * inv % p}; 
			
			if ((u ^ t) == (complex){1, 0}) puts("Yes");
			else puts("No");
		}
	}
	
	return 0;
}
posted @ 2024-01-20 14:45  PassName  阅读(26)  评论(0编辑  收藏  举报