bzoj2134: 单选错位(trie)

  预处理前后缀异或和,用trie得到前后缀最大答案,枚举中间点把左右两边加起来就是当前中间点的最大答案了...这个操作没见过,比较有意思,记录一下

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=500010, inf=1e9;
struct poi{int nxt[2];}tree[maxn*30];
int n, ans, tott;
int a[maxn], suml[maxn], sumr[maxn], ansl[maxn], ansr[maxn];
inline void read(int &k)
{
    int f=1; k=0; char c=getchar();
    while(c<‘0‘ || c>‘9‘) c==‘-‘&&(f=-1), c=getchar();
    while(c<=‘9‘ && c>=‘0‘) k=k*10+c-‘0‘, c=getchar();
    k*=f;
}
inline int getans(int x)
{
    int ans=0, now=0;
    for(int i=30, y;~i;i--)
    if(tree[now].nxt[(y=(x&(1<<i))!=0)^1])
    ans+=(1<<i), now=tree[now].nxt[y^1];
    else now=tree[now].nxt[y];
    return ans;
}
inline void insert(int x)
{
    int now=0;
    for(int i=30, y;~i;i--)
    if(tree[now].nxt[y=(x&(1<<i))!=0]) now=tree[now].nxt[y];
    else tree[now].nxt[y]=++tott, now=tott;
}
int main()
{
    read(n);
    for(int i=1;i<=n;i++) read(a[i]), suml[i]=suml[i-1]^a[i];
    for(int i=n;i;i--) sumr[i]=sumr[i+1]^a[i];
    insert(0);
    for(int i=1;i<=n;i++) ansl[i]=max(ansl[i-1], getans(suml[i])), insert(suml[i]);
    memset(tree, 0, sizeof(tree)); insert(0);
    for(int i=n;i;i--) ansr[i]=max(ansr[i+1], getans(sumr[i])), insert(sumr[i]);
    for(int i=1;i<=n;i++) ans=max(ans, ansl[i]+ansr[i]);
    printf("%d\n", ans);
}

原文地址:https://www.cnblogs.com/Sakits/p/8432400.html

时间: 2024-08-28 03:42:16

bzoj2134: 单选错位(trie)的相关文章

bzoj2134单选错位

bzoj2134单选错位 题意: 试卷上n道选择题,每道分别有ai个选项.某人全做对了,但第i道题的答案写在了第i+1道题的位置,第n道题答案写在第1题的位置.求期望能对几道.n≤10000000 题解: 水题,然而我不会.第i题与第i+1题答案一样的概率是1/max(aiai+1) 代码: 1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 int a[10000010],n,A,B,C; 6

BZOJ2134 单选错位

= =是道沙茶题,直接模拟即可... 1 /************************************************************** 2 Problem: 2134 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:1292 ms 7 Memory:78932 kb 8 ****************************************************************

BZOJ 2134: 单选错位( 期望 )

第i个填到第i+1个的期望得分显然是1/max(a[i],a[i+1]).根据期望的线性性, 我们只需将每个选项的期望值累加即可. --------------------------------------------------------------------------- #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 10000009; int a[maxn];

BZOJ_2134_单选错位——期望DP

BZOJ_2134_单选错位——期望DP 题意: 分析:设A为Ai ∈ [1,ai+1] 的概率,B为Ai = A(imodn+1)的概率显然P(A|B) = 1,那么根据贝叶斯定理P(B) = P(B|A)*P(A)P(A) = min(ai,ai+1)/aiP(B|A) = 1/a(i+1)P(B) = min(ai,ai+1)/(ai*a(i+1))又因为期望的可加性,直接加起来统计答案 代码: #include <stdio.h> #include <string.h> #

单选错位

单选错位 [问题描述] gx和lc去参加noip初赛,其中有一种题型叫单项选择题,顾名思义,只有一个选项是正确答案.试卷上共有n道单选题,第i道单选题有ai个选项,这ai个选项编号是1,2,3,-,ai,每个选项成为正确答案的概率都是相等的.lc采取的策略是每道题目随机写上1-ai的某个数作为答案选项,他用不了多少时间就能期望做对道题目.gx则是认认真真地做完了这n道题目,可是等他做完的时候时间也所剩无几了,于是他匆忙地把答案抄到答题纸上,没想到抄错位了:第i道题目的答案抄到了答题纸上的第i+1

【BZOJ2134】单选错位 概率DP? 貌似不算DP

转载请注明出处:http://blog.csdn.net/vmurder/article/details/42879121 题意:输入完了后,第i道题有ai种可能的正确选项,有ai-1种某人可能选的选项,问期望对多少题. 这道题的期望对于两道题之间是无关的. 只需要对每道题单独讨论 a种正确选项,b种可能选项 对于某种正确选项,某人有1/b的概率做对 总几率:1/b/a. 而这样的正确选项有min(a,b)种. 恩,就是这样. 代码: #include <cstdio> #include &l

【BZOJ2134】单选错位 概率DP

一句话:有一些看似有关系的期望在把事件全面发生之后就变得相互独立了 #include<cstdio> using namespace std; int n,A,B,C,a[10000001]; double ans; int main() { scanf("%d%d%d%d%d",&n,&A,&B,&C,a+1); for(int i=2;i<=n;i++)a[i]=((long long)a[i-1]*A+B)%100000001;

Bzoj2134:单选错位

题面 Bzoj Sol 第\(i\)道题选对的概率就是\(\frac{min(a[i-1], a[i])}{a[i]*a[i-1]}\) # include <bits/stdc++.h> # define RG register # define IL inline # define Fill(a, b) memset(a, b, sizeof(a)) using namespace std; typedef long long ll; const int _(1e7 + 5); const

[补档][国家集训队2011]单选错位

题目 gx和lc去参加noip初赛,其中有一种题型叫单项选择题,顾名思义,只有一个选项是正确答案. 试卷上共有n道单选题,第i道单选题有ai个选项,这ai个选项编号是1,2,3,-,ai,每个选项成为正确答案的概率都是相等的.lc采取的策略是每道题目随机写上1-ai的某个数作为答案选项,他用不了多少时间就能期望做对sigma(1/ai)道题目.gx则是认认真真地做完了这n道题目,可是等他做完的时候时间也所剩无几了,于是他匆忙地把答案抄到答题纸上,没想到抄错位了:第i道题目的答案抄到了答题纸上的第