最大割

Time Limit: 15 Sec  Memory Limit: 256 MB

Description

  

Input

  

Output

  

Sample Input

  3 6
  1 2 1
  1 2 1
  3 3 111
  1 3 101101
  1 2 1011
  2 3 111011

Sample Output

  1
  0
  0
  101101
  101101
  110000

HINT

  l = log2(w)

  

Solution

  首先我们发现,由于XOR满足消去律,那么我们定义一个新点的点权为该点所有连边的XOR和,那么任意点XOR起来得到的值正是割的值,所以这样操作之后问题就转化为了:任取几个点,求XOR出的最大值,支持点权修改。

  那么我们现在显然得到了做法:线性基,并且我们需要维护一个可修改的线性基。

  线性基的加入方法:1.从大到小加入,如果这一位没有匹配元则加入当前值当作匹配元,退出;2.如果这一位有匹配元了就XOR完向后继续执行操作,若值=0则退出

  线性基的最值方法:用一个初值为0的Ans串,从大到小贪心,如果这一位有匹配元并且Ans串该位为0则XOR,继续向后

  线性基的维护方法:我们另外记录一个record表示这个基是由哪些值XOR出来的,比如我们要消去b,然后我们就用一个 有bXOR出来且主元最小 的基来消去其它含b的基中的b,其中主元定义为最高位的1,我们让最高位的1最小,这样往上消去的时候依然可以满足XOR出来可以满足线性基的条件性质。然后我们扫一遍,如果含有这个b则XOR一下,并且record要XOR那个基的record,这样才可以保证record的记录不漏

  这道题就是先删除,然后再加入,每次询问求最值即可。

Code

 #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<bitset>
using namespace std; const int ONE = ;
const int L = ; int T,n,x,y;
int PD;
char s[ONE];
int Link[ONE]; bitset <L> record[ONE],A[ONE];
bitset <L> Ans,P; int get()
{
int res,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} void Deal_first()
{
scanf("%s",s+);
int len = strlen(s+);
P.reset();
for(int i=;i<=len;i++)
P[L-len+i] = s[i]-'';
} void Add(int k)
{
for(int pos=;pos<=L;pos++)
if(A[k][pos])
{
if(!Link[pos])
{
Link[pos] = k;
break;
}
else
{
A[k] ^= A[Link[pos]];
record[k] ^= record[Link[pos]];
if(!A[k].any()) break;
}
}
} void Update(int x)
{
int k=;
for(int i=;i<=n;i++)
if(record[i][x] && !A[i].any())
{
k=i;
break;
} if(!k)
{
for(int i=L;i>=;i--)
{
if(Link[i] && record[Link[i]][x])
{
k = Link[i];
Link[i] = ;
break;
}
}
} for(int i=;i<=n;i++)
{
if(i!=k && record[i][x])
{
A[i] ^= A[k];
record[i] ^= record[k];
}
} A[k] ^= P; Add(k);
} int main()
{
n=get(); T=get();
for(int i=;i<=n;i++) record[i][i] = ;
while(T--)
{
x=get(); y=get();
Deal_first();
Update(x); Update(y); Ans.reset(); PD=;
for(int i=;i<=L;i++)
{
if(Link[i] && !Ans[i]) Ans ^= A[Link[i]];
if(Ans[i]) PD=;
if(PD) printf("%d",Ans[i]?:);
}
if(!PD) printf("");
printf("\n");
}
}

最新文章

  1. (转)实现DataList的分页 新增列
  2. (转)理解MySQL——索引与优化
  3. Yocto开发笔记之《应用程序架构》(QQ交流群:519230208)
  4. 2012年第三届蓝桥杯C/C++程序设计本科B组决赛
  5. SPSS时间序列:频谱分析
  6. memcached缓存批量更新解决方案探讨
  7. 关于Linux的时间与时区
  8. NOI2014 起床困难综合症
  9. javascript 动态创建表格
  10. Access Toke调用受保护的API
  11. linux安全篇
  12. React 学习(五) ---- 条件和列表渲染
  13. Java 面向切面 AOP
  14. (WF, Debug) System.Xaml.XamlObjectWriterException: Cannot create unknown type &#39;{clr-namespace:xx;assembly=xx}xx&#39;.
  15. 集群服务器、负载均衡和session共享,C#的static变量
  16. VMware提示无法打开内核设备 \\.\Global\vmx86: 系统找不到指定的文件解决方案
  17. 机器人操作系统(ROS)在线实训平台学习实验指南
  18. Java 语言基础(一)
  19. WPF绑定数据源之RelativeSource
  20. Mycat-server-1.6.5 常见分片方式

热门文章

  1. 在Linux下通过rpm打包发布Java程序
  2. 线段树简单入门 (含普通线段树, zkw线段树, 主席树)
  3. 8.0 TochAction各种用法
  4. Leetcode 680.验证回文字符串
  5. LeetCode 4——两个排序数组中的中位数
  6. 搭建高可用的Eureka注册中心
  7. 用tensorflow实现自然语言处理——基于循环神经网络的神经语言模型
  8. [转]Hibernate入门:批量插入数据
  9. c# 生成dll
  10. NHibernate3.3.3 学习笔记1