Wannafly挑战赛14E无效位置

https://www.nowcoder.com/acm/contest/81/E

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

不想说啥,这题意看错好几次,区间不能合并起来算,直接用线性基维护区间异或最大值,区间分割用并查集维护

//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
#define cd complex<double>
#define ull unsigned long long
//#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0)

using namespace std;

const double g=10.0,eps=1e-12;
const int N=100000+10,maxn=1000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;

vector<ll> base[N];
ll ans[N],a[N],qu[N];
int fa[N];
bool ok[N];
int Find(int x)
{
    return fa[x]==x?x:fa[x]=Find(fa[x]);
}
void Merge(int x,int y)
{
    for(int i=0;i<base[y].size();i++)
    {
        ll te=base[y][i];
        for(int j=0;j<base[x].size();j++)
            te=min(te,te^base[x][j]);
        if(te)base[x].pb(te);
    }
}
int main()
{
    int n;scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]),fa[i]=i;
    for(int i=1;i<=n;i++)scanf("%lld",&qu[i]);
    ll res=0;
    for(int i=n;i>=1;i--)
    {
        ll x=a[qu[i]];
        ok[qu[i]]=1;
        for(int j=0;j<base[qu[i]].size();j++)
            x=min(x,x^base[qu[i]][j]);
        if(x)base[qu[i]].pb(x);
        if(qu[i]!=1&&ok[qu[i]-1])
        {
            int te=Find(qu[i]-1);
            Merge(qu[i],te);
            fa[te]=qu[i];
        }
        if(qu[i]!=n&&ok[qu[i]+1])
        {
            int te=Find(qu[i]+1);
            Merge(qu[i],te);
            fa[te]=qu[i];
        }
        vector<ll>pp;
        for(int j=0;j<base[qu[i]].size();j++)pp.pb(base[qu[i]][j]);
        sort(pp.begin(),pp.end());
        ll sum=0;
        for(int j=pp.size()-1;j>=0;j--)
            sum=max(sum,sum^pp[j]);
        res=max(res,sum);
        ans[i]=res;
    }
    for(int i=1;i<=n;i++)printf("%lld\n",ans[i]);
    return 0;
}
/***********************
10
169 816 709 896 58 490 97 254 99 796
4 2 3 10 5 6 1 8 9 7
***********************/
View Code

猜你喜欢

转载自www.cnblogs.com/acjiumeng/p/8906510.html
今日推荐