zoukankan      html  css  js  c++  java
  • Wannafly挑战赛14 E 线性基

    E 无效位置

    题目描述

    给一个1-base数组{a},有N次操作,每次操作会使一个位置无效。一个区间的权值定义为这个区间里选出一些数的异或和的最大值。求在每次操作前,所有不包含无效位置的区间的权值的最大值。
    输入描述:

    第一行读入一个正整数(1 <= n <= 105)

    第二行读入n个正整数,第i个表示a[i](0<= a[i] <= 109)

    第三行读入n个正整数,第i个表示x[i]即第i次操作的位置,保证x[i]互不相同。

    输出描述:

    输出n行答案

    示例1
    输入

    10
    169 816 709 896 58 490 97 254 99 796
    4 2 3 10 5 6 1 8 9 7

    输出

    1023
    994
    994
    994
    490
    490
    254
    254
    99
    97

    tags:
    把删除转为添加,从后往前添加,每次可以用线性基快速算出异或最大值。因为还有要合并的情况,要确定祖先,所以要用个并查集维护一下。

    //https://www.nowcoder.com/acm/contest/81/E
    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 200005;
    
    struct L_B
    {
        long long d[61], p[61];
        int cnt;
        L_B() {
            memset(d,0,sizeof(d));
            memset(p,0,sizeof(p));
            cnt=0;
        }
        bool Insert(long long val) { //插入
            for (int i=60;i>=0;i--)
                if (val&(1LL<<i)) {
                    if (!d[i]) { d[i]=val; break; }
                    val ^= d[i];
                }
            return val>0;
        }
        bool is_in(long long val) { //存在性
            for(int i=60; i>=0; --i) {
                if(val&(1LL<<i)) {
                    if(d[i]) val ^= d[i];
                }
            }
            return val==0;
        }
        long long query_max() { //最大值
            long long ret=0;
            for (int i=60;i>=0;i--)
                if ((ret^d[i])>ret)
                    ret^=d[i];
            return ret;
        }
        long long query_min() { //最小值
            for (int i=0;i<=60;i++)
                if (d[i]) return d[i];
            return 0;
        }
        void rebuild() {  //求 k 小值前加
            for (int i=60;i>=0;i--)
                for (int j=i-1;j>=0;j--)
                    if (d[i]&(1LL<<j))
                        d[i]^=d[j];
            for (int i=0;i<=60;i++)
                if (d[i]) p[cnt++]=d[i];
        }
        long long kthquery(long long k) { //k小值
            long long ret=0;
            if (k>=(1LL<<cnt))
                return -1;
            for (int i=60;i>=0;i--)
                if (k&(1LL<<i))
                    ret^=p[i];
            return ret;
        }
    } LB[N];
    L_B merge(const L_B &n1,const L_B &n2) //合并
    {
        L_B ret=n1;
        for (int i=60;i>=0;i--)
            if (n2.d[i])
                ret.Insert(n2.d[i]);
        return ret;
    }
    
    int n, fa[N], cnt;
    bool vis[N];
    int Find(int x) { return fa[x]==x ? x : fa[x]=Find(fa[x]); }
    void  Unite(int x, int y) {
        int fax = Find(x), fay = Find(y);
        fa[fax] = fay;
        LB[fay] = merge(LB[fax], LB[fay]);
    }
    ll  a[N], mx=0;
    int x[N], id[N];
    stack< ll > Stack;
    ll ans = 0;
    int main()
    {
        rep(i,0,N-1) fa[i] = i;
        scanf("%d", &n);
        rep(i,1,n) scanf("%lld", &a[i]);
        rep(i,1,n) scanf("%d", &x[i]);
        per(i,n,1)
        {
            vis[x[i]] = true;
            LB[++cnt].Insert(a[x[i]]);
            id[x[i]] = cnt;
            if(vis[x[i]-1]) Unite(id[x[i]-1], id[x[i]]);
            if(vis[x[i]+1]) Unite(id[x[i]+1], id[x[i]]);
            ans = max(ans, LB[cnt].query_max());
            Stack.push(ans);
        }
        while(!Stack.empty())
            printf("%lld
    ", Stack.top()), Stack.pop();
    
        return 0;
    }
    
  • 相关阅读:
    服务器操作nginx相关操作命令
    git使用命令
    超出隐藏显示
    微信小程序清除默认样式
    程序员提升之排查bug的能力
    call和apply的基本用法与区别
    vuejs 插件开发并发布到npm--(3)vue组件开发并发布
    vuejs 插件开发并发布到npm--(2)js插件开发
    vuejs 插件开发并发布到npm--(1)为什么要进行插件开发管理
    双机热备份和负载均衡的区别
  • 原文地址:https://www.cnblogs.com/sbfhy/p/9019647.html
Copyright © 2011-2022 走看看