• 【BZOJ5092】分割序列(高维前缀和)


    题意:对于一个长度为n的非负整数序列b_1,b_2,...,b_n,

    定义这个序列的能量为:f(b)=max{i=0,1,...,n}((b_1 xor b_2 xor...xor b_i)+(b_{i+1} xor b_{i+2} xor...xor b_n)) 其中xor表示按位异或(XOR)

    给定一个长度为n的非负整数序列a_1,a_2,...,a_n,请计算a的每个前缀的能量值。

    n<=3e5,0<=a[i]<=1e6

    思路:补ccpc的题被卡了,导致5h比赛后面2h都没了,查题解发现要用高维前缀和,先刷几题了解一下

    实际上对于i,预处理前缀xor和数组s,答案就是max s[i]+s[i]^s[j]

    考虑从高到低逐位确定

    如果s[i]当前位为1,则不管s[j]当前位为0或1贡献都是2^j

    如果s[i]当前位为0,则s[j]当前位为1的贡献是2^(j+1),当前位为0的贡献是0

    考虑如何快速判断是否存在高位不劣,当前位为1,低位随意的s[j](即超集)

    预处理一个数组f[i],f[i]表示对于所有j,i是0的位置j是0/1,i是1的位置j是1,所有合法的j的最小出现下标

    直接判断f[now+2^j]是否<=i即可

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 typedef unsigned int uint;
     5 typedef unsigned long long ull;
     6 typedef pair<int,int> PII;
     7 typedef pair<ll,ll> Pll;
     8 typedef vector<int> VI;
     9 typedef vector<PII> VII;
    10 //typedef pair<ll,ll>P;
    11 #define N  310000
    12 #define M  2000010
    13 #define fi first
    14 #define se second
    15 #define MP make_pair
    16 #define pb push_back
    17 #define pi acos(-1)
    18 #define mem(a,b) memset(a,b,sizeof(a))
    19 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
    20 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
    21 #define lowbit(x) x&(-x)
    22 #define Rand (rand()*(1<<16)+rand())
    23 #define id(x) ((x)<=B?(x):m-n/(x)+1)
    24 #define ls p<<1
    25 #define rs p<<1|1
    26 
    27 const ll MOD=1e9+7,inv2=(MOD+1)/2;
    28       double eps=1e-6;
    29       int INF=1e9;
    30       int dx[4]={-1,1,0,0};
    31       int dy[4]={0,0,-1,1};
    32 
    33 int f[M],a[N];
    34 
    35 int read()
    36 {
    37    int v=0,f=1;
    38    char c=getchar();
    39    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
    40    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
    41    return v*f;
    42 }
    43 
    44 int main()
    45 {
    46     int S=1<<20;
    47     rep(i,0,S) f[i]=INF;
    48     int n=read();
    49     rep(i,1,n)
    50     {
    51         a[i]=read();
    52         a[i]^=a[i-1];
    53         f[a[i]]=min(f[a[i]],i);
    54     }
    55     rep(i,0,19)
    56      rep(j,0,S-1)
    57       if(!(j>>i&1)) f[j]=min(f[j],f[j^(1<<i)]);
    58     rep(i,1,n)
    59     {
    60         int ans=0,now=0;
    61         per(j,19,0)
    62          if(a[i]>>j&1) ans+=(1<<j);
    63           else
    64           {
    65               if(f[now^(1<<j)]<=i) ans+=(1<<(j+1)),now^=(1<<j);
    66           }
    67         printf("%d
    ",ans);
    68     }
    69     return 0;
    70 }
  • 相关阅读:
    uva 10066 The Twin Towers (最长公共子)
    warning: directory not found for option &#39; &#39;
    Hadoop-2.4.0安装和wordcount执行验证
    Android中的动画具体解释系列【1】——逐帧动画
    python学习1(小白记录)
    Struts2 开发环境搭建
    SlidingMenu开源项目滑动界面的实现总结
    ubuntu终端方向键不能用(主机名不显示)问题的解决
    Gnu Linux--Ubuntu系统清理项整理
    Task Schedule
  • 原文地址:https://www.cnblogs.com/myx12345/p/11727922.html
Copyright © 2020-2023  润新知