题目:https://loj.ac/problem/2312

   https://www.luogu.org/problemnew/show/P3733

原本以为要线段树分治+LCT,查了查发现环上的值直接是 dis[ u ] ^ dis[ v ] ^ w[ i ] 就行了(其中 u , v 是边的两端, i 是边的标号)。

再看一下题,发现一开始一定是连通的。所以剩下的就和 bzoj 4184 shallot 一样用线性基就行了。

因为有 1000 位,所以用 bitset 。

线性基求最大值原来不用判断 if( ( ans^b[ i ] ) > ans ) ans ^= b[ i ] ,直接看 ans 的这一位上是不是 0 就行了。

线段树的一个点不要用 vector 存 bitset ,存一下边的编号,然后每条边开 bitset 存一下自己就行了,能省出很多空间。

在线段树上 dfs 求答案的时候不要把一个线性基带在参数上,给每个点用 vector 记录一下它改了线性基的哪些位就行了,这样好像对栈空间更友好。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<bitset>
#define ls Ls[cr]
#define rs Rs[cr]
#define pb push_back
#define BT bitset<M>
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
int Mx(int a,int b){return a>b?a:b;}
int Mn(int a,int b){return a<b?a:b;}
const int N=,M=;
int n,m,hd[N],xnt,to[M],nxt[M],fa[N],dy[/*N*/M],mx;
int tot,Ls[M<<],Rs[M<<];
char ch[M]; bool vis[/*N*/M];
BT dis[N],w[M],b[M],ew[M],tmp;
vector<int> vt[M<<],cg[M<<];
struct Ed{int x,y; BT w;}ed[/*N*/M]; void cz(BT k,int cr)
{
for(int i=mx-;i>=;i--)
{
if(!k[i])continue;
if(!b[i].any()){ b[i]=k;cg[cr].pb(i);break;}
else k^=b[i];
}
}
void print()
{
tmp.reset();
for(int i=mx-;i>=;i--)
if(!tmp[i])tmp^=b[i];
int st=mx-; for(;st>&&!tmp[st];st--);
for(;st>=;st--) putchar(tmp[st]+'');
puts("");
}
void rd1()
{
scanf("%s",ch); int len=strlen(ch);
mx=Mx(mx,len); tmp.reset();//
for(int i=,j=len-;i<len;i++,j--)
tmp[i]=(ch[j]-'');
}
int fnd(int a){return fa[a]==a?a:fa[a]=fnd(fa[a]);}
void add(int x,int y)
{
int u=fnd(x),v=fnd(y);
if(u==v)
{
ed[++tot].x=x; ed[tot].y=y; ed[tot].w=tmp;
}
else
{
fa[u]=v;
to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;w[xnt]=tmp;
to[++xnt]=x;nxt[xnt]=hd[y];hd[y]=xnt;w[xnt]=tmp;
}
}
void dfs(int cr,int fa)
{
for(int i=hd[cr],v;i;i=nxt[i])
if((v=to[i])!=fa)
{
dis[v]=dis[cr]^w[i]; dfs(v,cr);
}
}
void build(int l,int r,int cr)
{
if(l==r)return; int mid=l+r>>;
ls=++tot; build(l,mid,ls);
rs=++tot; build(mid+,r,rs);
}
void ins(int l,int r,int cr,int L,int R,int k)
{
if(l>=L&&r<=R){vt[cr].pb(k);return;}
int mid=l+r>>;
if(L<=mid)ins(l,mid,ls,L,R,k);
if(mid<R)ins(mid+,r,rs,L,R,k);
}
void dfs(int l,int r,int cr)
{
int sz=vt[cr].size();
for(int i=;i<sz;i++)cz(ew[vt[cr][i]],cr);
if(!ls)print();
else dfs(l,l+r>>,ls), dfs((l+r>>)+,r,rs);
sz=cg[cr].size();
for(int i=;i<sz;i++)b[cg[cr][i]].reset();
}
int main()
{
n=rdn();m=rdn();int Q=rdn();
for(int i=;i<=n;i++)fa[i]=i;
for(int i=,u,v;i<=m;i++)
{
u=rdn();v=rdn();rd1();
add(u,v);
}
dfs(,); int t2=tot;
if(Q){ tot=;build(,Q,);}
for(int i=,u;i<=t2;i++)
{
tmp=dis[ed[i].x]^dis[ed[i].y]^ed[i].w;
cz(tmp,);
}
int cnt=; tot=;
for(int i=,x;i<=Q;i++)
{
scanf("%s",ch);
if(ch[]=='A')
{
cnt++; dy[cnt]=i;
ed[cnt].x=rdn();ed[cnt].y=rdn();
rd1(); ed[cnt].w=tmp;
}
else if(ch[]=='a')
{
x=rdn();
ew[++tot]=dis[ed[x].x]^dis[ed[x].y]^ed[x].w;
ins(,Q,,dy[x],i-,tot); vis[x]=;
}
else
{
x=rdn(); rd1();
ew[++tot]=dis[ed[x].x]^dis[ed[x].y]^ed[x].w;
ins(,Q,,dy[x],i-,tot);
dy[x]=i; ed[x].w=tmp;
}
}
for(int i=;i<=cnt;i++)
if(!vis[i])
{
ew[++tot]=dis[ed[i].x]^dis[ed[i].y]^ed[i].w;
ins(,Q,,dy[i],Q,tot);
}
print();
if(Q)dfs(,Q,); return ;
}

LOJ 2312(洛谷 3733) 「HAOI2017」八纵八横——线段树分治+线性基+bitset的更多相关文章

  1. LOJ2312 LUOGU-P3733「HAOI2017」八纵八横 (异或线性基、生成树、线段树分治)

    八纵八横 题目描述 Anihc国有n个城市,这n个城市从1~n编号,1号城市为首都.城市间初始时有m条高速公路,每条高速公路都有一个非负整数的经济影响因子,每条高速公路的两端都是城市(可能两端是同一个 ...

  2. LOJ 3043: 洛谷 P5280: 「ZJOI2019」线段树

    题目传送门:LOJ #3043. 题意简述: 你需要模拟线段树的懒标记过程. 初始时有一棵什么标记都没有的 \(n\) 阶线段树. 每次修改会把当前所有的线段树复制一份,然后对于这些线段树实行一次区间 ...

  3. 【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横

    不知道为什么bzoj没有HAOI2017 题目描述 Anihc国有n个城市,这n个城市从1~n编号,1号城市为首都.城市间初始时有m条高速公路,每条高速公路都有一个非负整数的经济影响因子,每条高速公路 ...

  4. loj#2013. 「SCOI2016」幸运数字 点分治/线性基

    题目链接 loj#2013. 「SCOI2016」幸运数字 题解 和树上路径有管...点分治吧 把询问挂到点上 求出重心后,求出重心到每个点路径上的数的线性基 对于重心为lca的合并寻味,否则标记下传 ...

  5. LOJ 3045: 洛谷 P5326: 「ZJOI2019」开关

    题目传送门:LOJ #3045. 题意简述 略. 题解 从高斯消元出发好像需要一些集合幂级数的知识,就不从这个角度思考了. 令 \(\displaystyle \dot p = \sum_{i = 1 ...

  6. LOJ 3089: 洛谷 P5319: 「BJOI2019」奥术神杖

    题目传送门:LOJ #3089. 题意简述: 有一个长度为 \(n\) 的母串,其中某些位置已固定,另一些位置可以任意填. 同时给定 \(m\) 个小串,第 \(i\) 个为 \(S_i\),所有位置 ...

  7. LOJ 3093: 洛谷 P5323: 「BJOI2019」光线

    题目传送门:LOJ #3093. 题意简述: 有 \(n\) 面玻璃,第 \(i\) 面的透光率为 \(a\),反射率为 \(b\). 问把这 \(n\) 面玻璃按顺序叠在一起后,\(n\) 层玻璃的 ...

  8. LOJ 2483: 洛谷 P4655: 「CEOI2017」Building Bridges

    题目传送门:LOJ #2483. 题意简述: 有 \(n\) 个数,每个数有高度 \(h_i\) 和价格 \(w_i\) 两个属性. 你可以花费 \(w_i\) 的代价移除第 \(i\) 个数(不能移 ...

  9. LOJ 2249: 洛谷 P2305: 「NOI2014」购票

    题目传送门:LOJ #2249. 题意简述: 有一棵以 \(1\) 号节点为根节点的带边权的树. 除了 \(1\) 号节点的所有节点上都有人需要坐车到达 \(1\) 号节点. 除了 \(1\) 号节点 ...

随机推荐

  1. c#继承中的函数调用实例

    using System;   namespace Test {     public class Base     {         public void Print()         {   ...

  2. POJ2785-4 Values whose Sum is 0

    传送门:http://poj.org/problem?id=2785 Description The SUM problem can be formulated as follows: given f ...

  3. [转]TCP滑动窗口详解

    TCP滑动窗口详解  http://lyjdamzwf.blog.163.com/blog/static/75206837201193373226/ TCP滑动窗口(Sliding Window)   ...

  4. 强化学习中的无模型 基于值函数的 Q-Learning 和 Sarsa 学习

    强化学习基础: 注: 在强化学习中  奖励函数和状态转移函数都是未知的,之所以有已知模型的强化学习解法是指使用采样估计的方式估计出奖励函数和状态转移函数,然后将强化学习问题转换为可以使用动态规划求解的 ...

  5. 2017-2018-2 20165228 实验三《敏捷开发与XP实践》实验报告

    2017-2018-2 20165228 实验三<敏捷开发与XP实践>实验报告 相关知识点 (一)敏捷开发与XP 通过 XP准则来表达: 沟通 :XP认为项目成员之间的沟通是项目成功的关键 ...

  6. Java 构造器Constructor 继承

    Java默认构造方法 构造方法作用:初始化所定义的类的对象和属性. 构造方法没有返回类型. 2 继承中的构造器 子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式). 如果父类 ...

  7. NOI-1.1-10-字符表示超级玛丽

    10:超级玛丽游戏   总时间限制:  1000ms 内存限制:  65536kB 描述 超级玛丽是一个非常经典的游戏.请你用字符画的形式输出超级玛丽中的一个场景. 输入 无. 输出 如样例所示. 样 ...

  8. js中三种定义变量的方式const, var, let的区别。

    const   var  let区别 1.const 定义的变量不可以修改,而且必须初始化 const a = 3;正确 const a;错误,必须初始化 console.log("函数外c ...

  9. ATM-java

    通过学习JAVA,我的进步不是很多,了解了不多的编程知识,但是我一直在进步,我发现我有很大的进步空间,每天都有一点点的进步使我每天都很充实.还记得我编写的第一个 经典程序“hello Word”.从那 ...

  10. SQL-常用命令

    1.基本概念 SQL(Structured Query Language)结构化查询语言:一种对数据库进行操作的语言. DBMS:数据库管理系统. MySQL:一个数据库管理系统. 约束值:通过对表的 ...