The Nth Item

题目链接:https://nanti.jisuanke.com/t/41355

解题思路:其实这道题思路很简单,就是求出每一次的n1带进去算出F(n1),然后n2就是n1 xor F(n1)2,关键在于时间限制是1000ms;

本题采用 二次剩余定理+求逆元+光速幂

利用二次剩余定理+求逆元 可以将该方程转化为 f(n)=559329360(262199973n-736044383n)%998244353

转化过程采用暴力求 二次剩余和逆元

 1 //暴力求二次剩余
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 const int p=998244353;
 5 int main(int argc, char const *argv[])
 6 {
 7     for (long long i = 2; i < 10000000000; ++i)
 8     {
 9         if ((i*i-17)%p==0)
10         {
11             cout<<i<<endl;
12         }
13     }
14     return 0;
15 }

这里我们采用524399943(感觉随便用一个就行),暴力求逆元

 1 //暴力求524399943的逆元
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 const int p=998244353;
 5 int main(int argc, char const *argv[])
 6 {
 7     for (long long i = 2; i < 10000000000; ++i)
 8     {
 9         if ((i*524399943-1)%p==0)
10         {
11             cout<<i<<endl;
12         }
13     }
14     return 0;
15 }

这样便得到了559329360,同理,接下来根据求余的运算规则处理剩下的部分,最后得到方程f(n)=559329360(262199973n-736044383n)%998244353

接下来使用光速幂算法,便可以解出此题,关于光速幂的讲解网上有很多很详细的讲解,这里就不在复述了,代码如下:

 1 #include <bits/stdc++.h>
 2 #define RG register
 3 #define ll long long 
 4 using namespace std;
 5 
 6 
 7 const int N=5e4;//循环结
 8 const ll p=998244353;
 9 const ll k1=262199973;
10 const ll k2=736044383;
11 const ll a=559329360;
12 
13 ll f1[N+11];
14 ll f1x[N+11];
15 ll f2[N+11];
16 ll f2x[N+11];
17 
18 void init ()
19 {
20     f1[0]=1;
21     f1x[0]=1;
22     f2[0]=1;
23     f2x[0]=1;//why?
24     for (RG int i = 1; i <= N; ++i)
25     {
26         f1[i]=(f1[i-1]*k1)%p;
27         f2[i]=(f2[i-1]*k2)%p;
28     }
29     for (RG int i = 1; i <= N; ++i)
30     {
31         f1x[i]=((f1x[i-1]%p)*(f1[N]%p))%p;
32         f2x[i]=((f2x[i-1]%p)*(f2[N]%p))%p;
33     }
34 }
35 int main(int argc, char const *argv[])
36 {
37     init();
38     int n;
39     long long ans=0,fn,m1;
40     scanf("%d%lld",&n,&m1);
41     while(n--)
42     {
43         if (m1==0) break;
44         long long m=m1;
45         if (m>=p-1) m=m%(p-1)+(p-1);
46     
47         fn=((f1x[m/N]*f1[m%N])%p-(f2x[m/N]*f2[m%N])%p);
48         
49         fn=(fn%p+p)%p;
50 
51         fn=((fn%p)*(a%p))%p;
52 
53         ans^=fn;
54         m1=m1^(fn*fn);
55 
56     }
57     printf("%lld\n",ans);
58     return 0;
59 }

相关题目练习:https://www.luogu.org/problem/P5110

光速幂练习:https://www.csdn.net/link?target_url=https%3A%2F%2Fwww.luogu.org%2Fproblem%2FP1226&id=100174163&token=0a8a1eaf0e54cd3d2f06886fb428c6b5

posted @ 2019-09-16 23:54  DemonSlayer  阅读(203)  评论(0编辑  收藏  举报