题意:有一个长度为n的序列,给定某m个位置上的数如ai上有bi,其余的数可以任意,令ci表示ai的前缀异或和,求$\sum_{i=1}^{n}ci$的最小值,1<=m,bi<=n<=1e9,0<=ai<=1e9
空位分两种:1.之后的位置还是空位,这种空位一定可以贪心为0;2.之后的位置已经知道,这时候需要考虑是否要让后面的一段的每一位异或上1,即判断s0+1和s1的大小(si表示某位2进制中该段i的个数),贪心即可(注意第1个位置前没有空位)
View Code
1 #include<bits/stdc++.h> 2 using namespace std; 3 struct ji{ 4 int id,k; 5 bool operator < (const ji &a){ 6 return id<a.id; 7 } 8 }a[100005]; 9 int n,m,s[2][101]; 10 long long ans; 11 int main(){ 12 scanf("%d%d",&n,&m); 13 for(int i=1;i<=m;i++)scanf("%d%d",&a[i].id,&a[i].k); 14 sort(a+1,a+m+1); 15 bool flag=(a[1].id==1); 16 a[++m].id=n+2; 17 for(int i=1;i<=m;i++){ 18 if (a[i].id==a[i-1].id+1)a[i].k^=a[i-1].k; 19 else{ 20 for(int j=0;j<31;j++){ 21 if (flag)ans+=s[1][j]*(1LL<<j); 22 else ans+=min(s[0][j]+1,s[1][j])*(1LL<<j); 23 s[0][j]=s[1][j]=0; 24 } 25 printf("%lld ",ans); 26 flag=0; 27 } 28 for(int j=0;j<31;j++)s[((a[i].k&(1<<j))>0)][j]++; 29 } 30 printf("%lld",ans); 31 }