虽然我只过了95分但是还要写个题解,说不定什么时候RP好就A了,O(∩_∩)O哈哈~。
题面
一个神奇的复数 r=−1+7√i2,其中 i 是虚数单位 i2=−1。 对于任意整数x 和 y,
我们都可以找到⼀个有限的整数集合 S 使得x+y7√i=∑k∈Srk换句话说,我们将 x + y √7 i 转换为 r 进制,每位上是 0 或者 1。其中为 1的位置的集合记做 S 。
输入x 和y,从小到大输出集合 S 中的元素,可以证明 S 是唯一的。 集合中不能包含相同元素。
输入格式
一行两个整数表示 x, y。
输出格式
一行一个数组表示集合 S ,从小到大输出。
样例输入
7 1
样例输出
2 3 4 5 6 7
数据范围与提示
对于 100% 的数据,满足 |x|,|y|≤1018。
对于 50% 的数据,满足 y=0。
对于 50% 的数据,满足 |x|,|y|≤102。
以上两部分数据相交 25%。
思路
找规律,打一个rk的表,写个程序试试。
程序如下:
#include<algorithm>
#include<cmath>
#include<complex>
using namespace std;
typedef complex<double> cd;
#include<stdio.h>
#include<stdlib.h>
const cd r=cd(-1.0,sqrt(7.0))/2.0;
int main(){
cd rk(1,0);
for(int i=0;i<=15;i++){
printf("%5d: ",i);
printf("(%g + %g sqrt(7))/2\n",rk.real()*2,rk.imag()*2.0/sqrt(7.0));
rk*=r;
}
return 0;
}
运行结果:
0: (2 + 0 sqrt(7))/2
1: (-1 + 1 sqrt(7))/2
2: (-3 + -1 sqrt(7))/2
3: (5 + -1 sqrt(7))/2
4: (1 + 3 sqrt(7))/2
5: (-11 + -1 sqrt(7))/2
6: (9 + -5 sqrt(7))/2
7: (13 + 7 sqrt(7))/2
8: (-31 + 3 sqrt(7))/2
9: (5 + -17 sqrt(7))/2
10: (57 + 11 sqrt(7))/2
11: (-67 + 23 sqrt(7))/2
12: (-47 + -45 sqrt(7))/2
13: (181 + -1 sqrt(7))/2
14: (-87 + 91 sqrt(7))/2
15: (-275 + -89 sqrt(7))/2
惊奇的发现:当rk 被表示成 a+b7√i2 时,其中的a 与
定义命题P(x) 表示rx=a+b7√i2:a,b∈Z⇒a+b≡0mod4
首先,P(1):−1+1⋅7√i2a=−1,b=1 显然成立。
当P(x) 成立时有 rx=a+b7√i2:a,b∈Z⇒a+b≡0mod4
那么:
所以:
由此可得P(x):x∈N∗ 均成立。
也可以顺便证得另一个结论:
↑这个结论后文中会用到。
假设max(S)≤n ,用Si 表示集合S中从小到大数第i个元素(i大于元素总个数,令Si=0)。
再定义一个数列A1..n 满足
则有:
该式可以看成是一个关于r的n次多项式,可用秦九韶算法进行处理。
先分析A0 的值是多少,此时q=2x+2y⋅7√i2 ,若2x+2y≠0mod4 ,证明A0=1(因为它表示不成r的c倍的形式,c的定义见上文。)而当2x+2y≡0mod4,不难发现一定有 A0=0 成立,证明如下:
假设A0=1,那么有:
所以:
又因为:
所以:
即:q−1 不能表示成 c⋅r 的形式,显然与:
矛盾。
所以A0=0充要得证。
分析完A0 我们将q减去
代码
附上95分代码:
#include<stdio.h>
#include<stdlib.h>
struct complex{
long long real,imag;
};
typedef struct complex complex;
#define DEBUG (0)
#define debug if(DEBUG)
#define runtime if(!DEBUG)
int main(){
runtime{
freopen("verlauf.in","r",stdin);
freopen("verlauf.out","w",stdout);
}
long long x,y;
scanf("%lld%lld",&x,&y);
x*=2;y*=2;
debug{
printf("x=%lld y=%lld\n",x,y);
}
int i;
for(i=0;!(x==0 && y==0);i++){
debug printf("i=%d x=%lld y=%lld\n",i,x,y);
if((x+y)%4!=0){//has value
runtime printf("%d ",i);
debug printf("[%d] ",i);
x-=2;
}
long long nx=(7*y-x)/4;
long long ny=(-x-y)/4;
x=nx;y=ny;
}
return 0;
}