题目描述
给定一个长度为n的序列{a},求:
m
a
x
1
≤
i
≤
j
≤
n
max_{1\leq i\leq j \leq n}
max1≤i≤j≤n{
(
a
i
(a_i
(ai
⨁
\bigoplus
⨁
a
i
+
1
a_{i+1}
ai+1
⨁
\bigoplus
⨁
⋅
\cdot
⋅
⋅
\cdot
⋅
⋅
\cdot
⋅
⨁
\bigoplus
⨁
a
j
a_j
aj)+
(
a
i
(a_i
(ai
+
+
+
a
i
+
1
a_{i+1}
ai+1
+
+
+
⋅
\cdot
⋅
⋅
\cdot
⋅
⋅
\cdot
⋅
+
+
+
a
j
a_j
aj) }
m
o
d
mod
mod
100000007
100000007
100000007
其中
⨁
\bigoplus
⨁表示异或
输入描述
第一行一个整数
n
n
n。
第二行
n
n
n个整数,表示
a
i
a_i
ai。
输出描述
一行一个整数 a n s ans ans,表示答案。
题目大意
在数组 a a a中选择一个子序列使得式子 m a x 1 ≤ i ≤ j ≤ n max_{1\leq i\leq j \leq n} max1≤i≤j≤n{ ( a i (a_i (ai ⨁ \bigoplus ⨁ a i + 1 a_{i+1} ai+1 ⨁ \bigoplus ⨁ ⋅ \cdot ⋅ ⋅ \cdot ⋅ ⋅ \cdot ⋅ ⨁ \bigoplus ⨁ a j a_j aj)+ ( a i (a_i (ai + + + a i + 1 a_{i+1} ai+1 + + + ⋅ \cdot ⋅ ⋅ \cdot ⋅ ⋅ \cdot ⋅ + + + a j a_j aj) } 最大,输出最大值mod 100000007 100000007 100000007结果。
解题思路
不知道为什么,拿到数学题就觉得头痛,刚开始完全没有思路。但水了一会儿牛客的交流群之后就突发奇想是不是所有数都选的时候就是最大的,没想到最后AC了。证明过程就借用一下官方题解的证明。
但自己最后也通过自己的方式想明白了其中的原理,两个数
a
,
b
a,b
a,b异或,如果
a
,
b
a,b
a,b相同的话,异或之后变为
0
0
0,其他情况都不会变为
0
0
0,也就是说异或之后值最大的减小量为
b
b
b,最后再加上
b
b
b的话,最后值的大小要么增大要么不变,不可能变小。式子
m
a
x
1
≤
i
≤
j
≤
n
max_{1\leq i\leq j \leq n}
max1≤i≤j≤n{
(
a
i
(a_i
(ai
⨁
\bigoplus
⨁
a
i
+
1
a_{i+1}
ai+1
⨁
\bigoplus
⨁
⋅
\cdot
⋅
⋅
\cdot
⋅
⋅
\cdot
⋅
⨁
\bigoplus
⨁
a
j
a_j
aj)+
(
a
i
(a_i
(ai
+
+
+
a
i
+
1
a_{i+1}
ai+1
+
+
+
⋅
\cdot
⋅
⋅
\cdot
⋅
⋅
\cdot
⋅
+
+
+
a
j
a_j
aj) } 最大自然而然就是把所有数都选上。
AC代码
#include <bits/stdc++.h>
#define INF 0x3f3f3f
using namespace std;
const int mod=1e8+7;
const int Max_N=3e5+5;
typedef pair<int,int>P;
typedef long long ll;
typedef unsigned long long ull;
int main(int argc, char const *argv[])
{
ll res=0,mid1=0,mid2=0;
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
mid1^=x;
mid2+=x;
}
res=mid2+mid1;
res%=mod;
cout<<res<<endl;
return 0;
}
总结
唉,这道题也是wa了两次,第一次思路是对的,但是自己忘记取模了,对了,这道题真的很毒瘤,正常情况都是对1e9+7取模,看到100000007一般不用想都是1e9+7,然而这道题是1e8+7,所以保险起见还是去数一下位数吧。第二次以为自己第一次的思路是错的,想了另外一种方法,但是t了,最后还是回到了第一种方法。