我们按位做,就是一堆01串,有一些位置还未确定,求最小异或前缀和的和。我们发现,对于连续的一段确定的01串,记长度为n,异或和的和为m(个1),则我们可以通过给定这个连续确定串的前一个位置为0/1,得到min(m,n-m+1)的最优和。(根据上一个连续串最后的和是0还是1决定这个连续串的前面填上一个0还是1来取得最优的和)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100010
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n,m,bin[32],mx=0;ll ans=0;
struct data{
int pos,x;
}a[N];
inline bool cmp(data a,data b){return a.pos<b.pos;}
inline int solve(int bit){
int res=0,now=1,sum=0,len=0,cnt=0;
while(now<=m&&a[now].pos==now) sum^=(a[now].x>>bit)&1,res+=sum,++now;
if(now>m) return res;
sum=(a[now].x>>bit)&1;len=1;cnt=sum;
for(int i=now+1;i<=m;++i){
if(a[i].pos!=a[i-1].pos+1){
res+=min(cnt,len-cnt+1);sum=0;len=0;cnt=0;
}sum^=(a[i].x>>bit)&1;len++;cnt+=sum;
}res+=min(cnt,len-cnt+1);return res;
}
int main(){
// freopen("a.in","r",stdin);
n=read();m=read();
for(int i=1;i<=m;++i) a[i].pos=read(),a[i].x=read(),mx=max(mx,a[i].x);
sort(a+1,a+m+1,cmp);bin[0]=1;
for(int i=1;i<=30;++i) bin[i]=bin[i-1]<<1;
for(int i=0;i<=30&&mx>=bin[i];++i) ans+=(ll)bin[i]*solve(i);
printf("%lld\n",ans);
return 0;
}