【位运算】大河的序列

D e s c r i p t i o n Description Description

大河有一些袜子,但经常十分散乱的堆放着。

有一天龙儿忍不住了,于是将袜子放到了一个序列上(称作袜子序列)。

每个袜子都有一个 d i r t y dirty dirty值,定义袜子序列的 d i r t y dirty dirty值为 max ⁡ ( ( d i r t y l   b i t a n d   d i r t y l + 1   b i t a n d   ⋯   b i t a n d   d i r t y r ) + ( d i r t y l   b i t o r   d i r t y l + 1   b i t o r   ⋯   b i t o r   d i r t y r ) ) m a x ( ( d i r t y l ​ b i t a n d d i r t y l + 1 ​ b i t a n d ⋯ b i t a n d d i r t y r ​ ) + ( d i r t y l b i t o r d i r t y l + 1 ​ b i t o r ⋯ b i t o r d i r t y r ​ ) ) \max \left( (dirty_{l} \ bitand \ dirty_{l+1} \ bitand \ \cdots \ bitand \ dirty_{r}) + (dirty_{l} \ bitor \ dirty_{l+1} \ bitor \ \cdots \ bitor \ dirty_{r}) \right) max((dirty l​ bitand dirty l+1​ bitand ⋯ bitand dirty r​ )+(dirty lbitor dirty l+1​ bitor ⋯ bitor dirty r​ )) max((dirtyl bitand dirtyl+1 bitand  bitand dirtyr)+(dirtyl bitor dirtyl+1 bitor  bitor dirtyr))max((dirtylbitanddirtyl+1bitandbitanddirtyr)+(dirtylbitordirtyl+1bitorbitordirtyr)) ,其中 d i r t y i dirty_{i} dirtyi表示 第 i i i只袜子的 d i r t y dirty dirty值, b i t a n d bitand bitand表示按位与(C++中是&), b i t o r bitor bitor表示按位或(C++中是|)。

简而言之,就是找一段连续子序列,使得所有数字的按位与加上按位或最大。

如果这个袜子序列的 d i r t y dirty dirty值达到了某个阈值,那么龙儿会讨厌大河的。

大河当然不希望这样了,于是她想知道这个袜子序列的dirtydirty值是多少。

I n p u t Input Input

第一行三个整数 n , b , p n,b,p n,b,p ,分别表示数列长度和输出相关的东西

第二行有 n n n个整数,表示这个数列的初始数值

O u t p u t Output Output

设答案为 x x x,你需要输出 ( x + 233 ) b    mod    p (x+233)^{b} \,\, \text{mod} \,\,p (x+233)bmodp

S a m p l e I n p u t Sample Input SampleInput
10 1 10000000
7 9 9 4 0 0 8 8 4 7
S a m p l e O u t p u t Sample Output SampleOutput
251

说明

1 ≤ n , p ≤ 1 0 5 1 \le n, p \le 10^{5} 1n,p105
0 ≤ b , d i r t y i ≤ 1 0 7 0 \le b, dirty_{i} \le 10^{7} 0b,dirtyi107

思路

我们先对每一次操作做分析
&:
d i r t y i dirty_{i} dirtyi:0
那么做下一次与运算时,结果都是0
d i r t y i dirty_{i} dirtyi:1
那么做下一次与运算是,结果要么1要么0,也就是要么更小要么不变
|:
d i r t y i dirty_{i} dirtyi:0
那么做下一次或运算时,结果要么1要么0,也就是要么更小要么更大
d i r t y i dirty_{i} dirtyi:1
那么做下一次或运算是,结果都是1,就是不变
但是我们发现
替代还不如直接换成下一个数
所以直接求数列中最大的数就行了

#include<algorithm>
#include<iostream> 
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;
ll Maxx ,n ,b ,p ,k;
ll Counting(ll n, ll b, ll p)//快速幂
{
	ll Ans = 1;
	n %= p;
	while(b)
	{
		if(b & 1) Ans = Ans * n % p;
		n = n * n % p;
		b >>= 1; 
	}
	return Ans % p;
}
int main()
{
	scanf("%lld%lld%lld" ,&n ,&b ,&p);
	for(int i = 1; i <= n; ++i)
	{
		scanf("%lld" ,&k);
		Maxx = max(Maxx, k);
	}
	Maxx *= 2;
	printf("%lld" ,Counting(Maxx + 233 ,b ,p));
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值