题目戳
Solution:
这题前面都是废话,关键的一句就是本题求的是序列中连续一段的相与值(&)+相或值(|)最大,然后对这个值进行快速幂取模。考虑到两个数相与最大能得到的就是这两个数中的最大值,两个数相或最大能得到的也是这两个数中的最大值,而题目中的连续一段可以是一个数,所以我们直接找出序列中的最大数。那么,连续一段的相与值+相或值最大就是 最大数*2,然后对这个数快速幂取模就ok了。(注意:题目中b可以为0,按理说输出是1,但是莫名其妙数据中要输出0)
代码:
1 // luogu-judger-enable-o2 2 #include<bits/stdc++.h> 3 #define ll long long 4 #define il inline 5 using namespace std; 6 ll n,p,b,a[100005],num; 7 il void gi(ll &c) 8 { 9 c=0;char x=getchar();bool f=0; 10 while((x<‘0‘||x>‘9‘))x=getchar(); 11 while(x>=‘0‘&&x<=‘9‘)c=c*10+x-48,x=getchar(); 12 } 13 il ll fast(ll x,ll b) 14 { 15 ll a=1; 16 while(b){ 17 if(b&1)a=a*x%p; 18 b>>=1; 19 x=x*x%p; 20 } 21 return a; 22 } 23 int main() 24 { 25 gi(n),gi(b),gi(p); 26 if(b==0){printf("0");return 0;} 27 for(int i=1;i<=n;i++)gi(a[i]),num=max(a[i],num); 28 num<<=1; 29 printf("%lld",fast(num+233,b)); 30 return 0; 31 }