【结论】大河的序列

L i n k Link Link

l u o g u luogu luogu P 4144 P4144 P4144

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

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

有一天龙儿忍不住了,于是将袜子放到了一个序列上(称作袜子序列)。
在序列里,找一段连续子序列,使得所有数字的按位与加上按位或最大。

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 (x+233)^b (x+233)b m o d mod mod p p p

S a m p l e Sample Sample I n p u t Input Input

10 1 10000000
7 9 9 4 0 0 8 8 4 7

S a m p l e Sample Sample O u t p u t Output Output

 251

H i n t Hint Hint

1 < = n , p < = 1 0 5 1 <= n,p <= 10^5 1<=n,p<=105
0 < = b , d i r t y [ i ] < = 1 0 7 0 <= b,dirty[i] <= 10^7 0<=b,dirty[i]<=107
对于测试点 1 1 1 和测试点 2 2 2 的数据,保证 1 ≤ n ≤ 100 1≤n≤100 1n100

T r a i n Train Train o f of of T h o u g h t Thought Thought

其实这道题可以通过推到得出结论:
x x x当前已找到最优序列,现在找到一个新的数 y y y,若将 y y y插入序列,运算到 d i r t y [ x ] dirty[x] dirty[x]的第 i i i位与 d i r t y [ y ] dirty[y] dirty[y]的对应位时,可分以下情况
1. d i r t y [ x ] [ i ] = = 1 dirty[x][i] == 1 dirty[x][i]==1,此时,若 d i r t y [ y ] [ i ] dirty[y][i] dirty[y][i] 1 1 1,则没有变化,若 d i r t y [ y ] [ i ] dirty[y][i] dirty[y][i] 0 0 0,则会更差(与运算变为0,或运算不变)
2. d i r t y [ x ] [ i ] = = 0 dirty[x][i] == 0 dirty[x][i]==0,此时,若 d i r t y [ y ] [ i ] dirty[y][i] dirty[y][i] 1 1 1,则会加到 1 1 1,若 d i r t y [ y ] [ i ] dirty[y][i] dirty[y][i] 0 0 0,则不变
四种情况中,只有一种能加到,而且加了之后,只对 x x x有好处,对 y y y则毫无益处(不会使得值更优)
因此,我们只选择一个数。
要选择一个数,那么肯定选择最大的数,进行运算后,就是这个数的2倍,最后再按题意进行处理
所以,题目最终解法就是:
a n s = m a x ( d i r t y [ i ] ) ∗ 2 ans = max(dirty[i]) * 2 ans=max(dirty[i])2 加上题目要求的输出处理

C o d e Code Code

#include<cstdio> 
#include<iostream>
using namespace std;
int n, b, p, maxn;
int a[100005];
int Counting(int x, int y, int p)
{
	int ans = 1;
	x = x % p;
	while (y)
	{
		if (y & 1) 
			ans = (long long) ans * x % p;
		x = (long long) x * x % p;
		y /= 2;
	}
	return ans;
}//快速幂
int main()
{
	scanf("%d%d%d", &n, &b, &p);
	for (int i = 1; i <= n; ++i)
	{
		scanf("%d", &a[i]);
		maxn = max (a[i],maxn);
	}
	maxn *= 2;
	if (p == 1) printf("0");
	 else printf("%d", Counting(maxn + 233, b, p));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值