列表

详情


NC14500. 可做题

描述

qmqmqm希望给sublinekelzrip出一道可做题。于是他想到了这么一道题目:给一个长度为n的非负整数序列ai,你需要计算其异或前缀和bi,满足条件b1=a1,bi=bi-1 xor ai(i >= 2).
但是由于数据生成器出现了问题,他生成的序列a的长度特别长,并且由于内存空间不足,一部分ai,已经丢失了,只剩余m个位置的元素已知。现在qmqmqm找到你,希望你根据剩余的ai,计算出所有可能的a序列对应的b序列中的最小值。

输入描述

输入第一行两个非负整数n,m,分别表示原始序列a的长度及剩余元素的个数。

之后m行,每行2个数i,ai,表示一个剩余元素的位置和数值。

输出描述

输出一个整数表示可能的最小值。

示例1

输入:

5 3
4 0
3 7
5 0

输出:

7

说明:

已知的a序列为:X,X,7,0,0,其中`X`表示这个位置丢失了。一种可能的a序列为0,7,7,0,0,对应的b序列为0,7,0,0,0,和最小为7。可以证明不存在和更小的情况。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++ 11.0.1) 解法, 执行用时: 50ms, 内存消耗: 1984K, 提交时间: 2023-07-12 09:00:21

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long ll;
typedef struct lalala
{
    int id,x;
}vt;
vt v[N];
bool cmp(lalala a,lalala b)
{
    return a.id<b.id;
}
ll b[N];
ll solve(int l,int r)
{
    ll ans=0,res=0;
    for(int i=l;i<=r;++i)
    res^=v[i].x,b[i]=res,ans+=res;
    if(v[l].id==1) return ans;
    ans=0;
    for(int k=0;k<=30;++k)
    {
        ll c1=1<<k,c2=0;
        for(int i=l;i<=r;++i)
        {
            if((b[i]>>k)&1) c2+=1<<k;
            else c1+=1<<k;
        }
        ans+=min(c1,c2);
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(false);
   int n,m;
    cin>>n>>m;int a,b;
    for(int i=1;i<=m;++i)
    {
        cin>>a>>b;
        v[i]={a,b};
    }
    sort(v+1,v+m+1,cmp);
    int j=1;
    ll ans=0;
    for(int i=1;i<=m;i=j)
    {
        while(j<=m&&v[j].id+1==v[j+1].id) j++;
        ans+=solve(i,j);
        ++j;
    }
    cout<<ans;
    return 0;
}

上一题