CodeForces - 1543D2 RPD and Rap Sheet (Hard Version)(交互+模拟)

Posted Frozen_Guardian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces - 1543D2 RPD and Rap Sheet (Hard Version)(交互+模拟)相关的知识,希望对你有一定的参考价值。

题目链接:点击查看

题目大意:交互题猜密码,设原密码为 x x x,猜的密码为 y y y,如果没猜到,密码会自适应变成 z z z,满足 x ⊕ z = y x \\oplus z=y xz=y ,最多猜 n n n 次,对于本题而言,所有数字是在 k k k 进制下进行的

题目分析:相对于 e a s y easy easy 版本而言,当异或推广到 k k k 进制时,就不存在自反性了,所以本题还是要稍微推一下公式找找共性

这里的异或就不能称之为异或了,下文中, ⊕ \\oplus 将视为 “k进制不进位加法”,同样对应一个 ⊖ \\ominus 为 “k进制不退位减法”,意义为名称所述。本题中的异或其实就是“k进制不进位加法”,需要提前知道的是,这两个运算同样具有基本运算的交换律和结合律的性质。

开始推公式,假设原答案为 x x x,猜的密码为 y y y,新密码为 z z z,因为满足 x ⊕ z = y x \\oplus z=y xz=y,两侧同时“不进位减去x”,得到 z = y ⊖ x z=y \\ominus x z=yx

假设第 i i i 次询问的值为 q i q_i qi,密码为 p a s s w o r d password password,第一次询问后,原密码变成了 q 1 ⊖ p a s s w o r d q_1 \\ominus password q1password;第 k k k 次询问后,原密码变成了 q k ⊖ ( q k − 1 ⊖ . . . ( q 2 ⊖ ( q 1 ⊖ p a s s w o r d ) ) ) q_k \\ominus(q_{k-1}\\ominus...(q_2 \\ominus (q_1 \\ominus password))) qk(qk1...(q2(q1password))),这里还是令 q 1 = 0 q_1=0 q1=0

所以假如我们第 i i i 次猜,想要猜原密码是否和 x x x 相等,也就是 p a s s w o r d = = x password==x password==x 是否成立,就必须令 q i = q i − 1 ⊖ ( q i − 2 ⊖ . . . ( q 2 ⊖ ( q 1 ⊖ x ) ) ) q_i=q_{i-1} \\ominus(q_{i-2}\\ominus...(q_2 \\ominus (q_1 \\ominus x))) qi=qi1(qi2...(q2(q1x)))

现在问题是如何快速求出 q i q_i qi。根据结合律,不难将 x x x 单独拿出来,然后整个式子就变成了: q i = q i − 1 ⊖ ( q i − 2 ⊖ . . . ( q 2 ⊖ q 1 ) )    o p    x q_i=q_{i-1} \\ominus(q_{i-2}\\ominus...(q_2 \\ominus q_1))\\ \\ op\\ \\ x qi=qi1(qi2...(q2q1))  op  x,这里的 o p op op 代表的是一个符号,这里先按下不表。不难看出 o p op op 前面的部分可以线性维护得到。而后面单独拆出来的 x x x,因为遇到减法拆括号时需要变号,“不进位减法” 在这里也是同理,所以当询问的下标为奇数时, o p op op ⊖ \\ominus ,当询问的下标为偶数时, o p op op ⊕ \\oplus

然后自己模拟一下 ⊕ \\oplus ⊖ \\ominus 这两个运算就可以了,按照上面的理论,将 n n n 个数字都枚举一遍, 时间复杂度是 O ( n l o g k n ) O(nlog_kn) O(nlogkn)

代码:

// Problem: D2. RPD and Rap Sheet (Hard Version)
// Contest: Codeforces - Codeforces Round #730 (Div. 2)
// URL: https://codeforces.com/contest/1543/problem/D2
// Memory Limit: 256 MB
// Time Limit: 5000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#define lowbit(x) x&-x
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{
    T f=1;x=0;
    char ch=getchar();
    while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    x*=f;
}
template<typename T>
inline void write(T x)
{
    if(x<0){x=~(x-1);putchar('-');}
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=1e6+100;
int k;
int add(int a,int b) {
	int ans=0,base=1;
	while(a||b) {
		int tmp=(a%k+b%k)%k;
		ans+=tmp*base;
		base*=k;
		a/=k,b/=k;
	}
	return ans;
}
int sub(int a,int b) {
	int ans=0,base=1;
	while(a||b) {
		int tmp=(a%k-b%k+k)%k;
		ans+=tmp*base;
		base*=k;
		a/=k,b/=k;
	}
	return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
//	freopen("data.in.txt","r",stdin);
//	freopen("data.out.txt","w",stdout);
#endif
//	ios::sync_with_stdio(false);
	int w;
	cin>>w;
	while(w--) {
		int n,sum=0;
		read(n),read(k);
		for(int i=0;i<n;i++) {
			int cur=1;
			if(i==0) {
				cur=0;
			} else if(i&1) {
				cur=sub(sum,i);
			} else {
				cur=add(sum,i);
			}
			printf("%d\\n",cur);
			fflush(stdout);
			int ans;
			scanf("%d",&ans);
			if(ans==1) {
				break;
			} else {
				sum=sub(cur,sum);
			}
		}
	}
    return 0;
}

以上是关于CodeForces - 1543D2 RPD and Rap Sheet (Hard Version)(交互+模拟)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #730 (Div. 2) D. RPD and Rap Sheet (交互,从easy到hard)

RPD Volume 168 Issue 4 March 2016 评论3

RPD Volume 168 Issue 4 March 2016 评论6

RPD Volume 168 Issue 4 March 2016 评论5

RPD Volume 168 Issue 4 March 2016 评论4

RPD Volume 168 Issue 4 March 2016 评论2