牛客小白月賽9: F. 暴力出奇跡(思維題)
阿新 • • 發佈:2018-11-23
連結:https://ac.nowcoder.com/acm/contest/275/F
來源:牛客網
題目描述
給定一個序列,尋找一對l,r,滿足1 ≤ l ≤ r ≤ n
最大化的值
其中表示將al,al+1, ... , ar按位與後的結果
輸入描述:
第一行一個整數n,表示數列長度. 第二行有n個整數,表示這個數列的初始數值.
輸出描述:
一行一個整數表示答案.
輸入
10 7 9 9 4 0 0 8 8 4 7
輸出
162
設dp[x][i] = 最小的p滿足a[p+1]&a[p+2]&…&a[x]的第i位為一
那麼暴力每個數字a[x],按照dp[x][i]的大小排序貪心求當前最大值就行了
看程式碼很好懂
#include<stdio.h> #include<string.h> #include<algorithm> #include<map> #include<string> #include<math.h> #include<queue> #include<stack> #include<iostream> using namespace std; #define LL long long #define mod 1000000007 LL sum[100005]; int a[100005], dp[100005][22]; typedef struct Res { int val, l; bool operator < (const Res &b) const { if(l<b.l) return 1; return 0; } }Res; Res s[22]; int main(void) { LL ans, now; int n, i, j; scanf("%d", &n); for(i=1;i<=n;i++) { scanf("%d", &a[i]); sum[i] = sum[i-1]+a[i]; } for(i=1;i<=n;i++) { for(j=0;j<=20;j++) { dp[i][j] = 0; if(a[i]&(1<<j)) dp[i][j] = dp[i-1][j]+1; } } ans = 0; for(i=1;i<=n;i++) { for(j=0;j<=20;j++) { s[j].val = (1<<j); s[j].l = i-dp[i][j]; } now = 0; sort(s, s+21); for(j=0;j<=20;j++) { now ^= s[j].val; ans = max(ans, now*(sum[i]-sum[s[j].l])); } } printf("%lld\n", ans); return 0; }