[mine518]

题意:有一个长度为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个位置前没有空位)
 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 }
View Code

猜你喜欢

转载自www.cnblogs.com/PYWBKTDA/p/11291019.html
518