八纵八横

题目描述

Anihc国有n个城市,这n个城市从1~n编号,1号城市为首都。城市间初始时有m条高速公路,每条高速公路都有一个非负整数的经济影响因子,每条高速公路的两端都是城市(可能两端是同一个城市),保证任意两个城市都可以通过高速公路互达。

国正在筹划“八纵八横”的高铁建设计划,计划要修建一些高速铁路,每条高速铁路两端也都是城市(可能两端是同一个城市),也都有一个非负整数的经济影响因子。国家还计划在“八纵八横”计划建成之后,将“一带一路”扩展为“一带_路一环”,增加“内陆城市经济环”即选择一条从首都出发沿若一系列高铁与高速公路走的路径,每条高铁或高速公路可以经过多次,每座城市也可以经过多次,最后路径又在首都结束。令“内陆城市经济环”的GDP为依次将这条路径上所经过的高铁或高速公路的经济影响因子异或起来(一条路经过多次则会被计算多次)。

现在Anihc在会议上讨论“八纵八横”的建设计划方案,他们会不断地修改计划方案,希望你能实时反馈对于当前的“八纵八横”的建设计划的方案“内陆城市经济环”的最大是多少。

初始时,八纵八横1计划中不包含任何—条高铁,有以下3种操作

  • Add x y z

在计划中给在城市x和城市y之间建设一条高铁,其经济影响因子为z,如果这是第k个Add操作,则将这条高铁命名为k号高铁

  • Cancel k

将计划中的k号高铁取消掉,保证此时k号高铁一定存在

  • Change k z

表示将第k号高铁的经济影响因子更改为z,保证此时k号高铁一定存在

输入格式

第一行3个整数n,m,P,表示城市个数.高速公路条数.操作个数

接下来m行.每行3个整数表示高速公路的信息。

接下来P行.每行为一个操作

注意:输入的所有经济影响因子都将以二进制的形式从高位到低位给出。

输出格式

第一行一个整数.表示如果不修建任何高铁,“内陆城市经济环”的GDP最大值

接下Q行.每行一个整数.表示进行了对应的每一个操作之后.对于当前的计划.“内 陆城市经济环”的CDP最大值。

注意:输出的答案也要以二进制的形式从高位到低位给出。

输入输出样例

输入 #1

4 4 3
1 2 1110
1 3 10
2 4 1110
2 3 100
Add 3 4 11
Change 1 101
Cancel 1

输出 #1

1000
1001
1111
1000

说明/提示

【数据规模与约定】

令所有的经济因子二进制表示的最多位数为len.数据满足以下表格

对于所有的数据保证:n,m<=500,Q,len<=1000,1<x,y<n.且Add操作不超过500个.两个城市之间可能有多条高速公路或高铁,高速公路或高铁的两端可能是同一个城市(即 有重边.有自环)。


题解

注意题意,它原先就有一个连通无向图,后来附加了一些边。

由于它是无向图,且每条边可以走多次,所以他的最大权值环的权值就是图中任选一些环权值异或起来的最大值,这应该很好理解,因为考虑走到一个环和走回去,来和去的路径权值异或起来为零,没有影响,所以如果当前异或一个图中的环权值可以更大的话,那么走一遍这个环后肯定是更优的(但是并不代表这题是贪心,听我讲)。

所以我们可以考虑用线性基。

把环的权值都放进线性基里,最后算出答案。

注意,并不是要把所有可以形成的环都放进去,由于线性基的性质,只需要保证放进去的所有环组成的子图内包含了原图的所有环就可以了,举个例子,假设这么一张图:

那么我们只需要放入“A-B-C-D”、“A-B-D”、“B-C-D”三个环中的任意两个。


由于它放入的边要改权值,并且要删边,线性基不支持删边,所以(观察数据发现)我们可以用线段树分治,这样就可以把删边、改权值全都变成加边操作,只是多了个2的常数(吧?

要维护每次加边后增加的环,看似有点麻烦,但是我们可以证明每加一次边最多只会在线性基里多加一个环,而且由于原本就是一个连通图,所以可以随便建一个生成树,然后把多余的边(每条可以对应一个环!)计算对应的环——即两端点连向lca的环的权值插入线性基,Add操作加的边也是一个道理。

最后由于它的二进制数有1000位,我们必须用bitset来打线性基,其中需要一些卡空间的技巧。

WARNING:要特判P=0的情况

CODE

#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>
#include<map>
#include<cmath>
#include<bitset>
#include<iostream>
#define MAXN 7005
#define LL long long
#define ULL unsigned LL
#define rg register
#define lowbit(x) (-(x) & (x))
#define ENDL putchar('\n')
#define DB double
#define bs bitset<1005>
#pragma GCC optimize(2)
//#pragma G++ optimize(3)
//#define int LL
using namespace std;
inline int read() {
int f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-') f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 - '0' + s;s = getchar();}
return x * f;
}
struct it{
int v,id;
it(){id = v = 0;}
it(int V,int I){v = V;id = I;}
};
int n,m,i,j,s,o,k;
bs w0[MAXN],w[MAXN],sum[MAXN];
int u[MAXN],v[MAXN],tm[MAXN];
vector<it> g[MAXN];
int f[MAXN],d[MAXN],fe[MAXN];
bool vis[MAXN];
bs ans[MAXN],lc[MAXN]; inline int highbit(bs x) {
// int as = -1;while(x) as ++,x >>= 1;return as;
int l = 0,r = 1000,mid;
while(l^r) {
mid = (l + r) >> 1;
// printf("1ll<<%d[%lld] <= %d ? %s\n",mid,1ll<<mid,x,(1ll<<mid) <= x ? "Yes!":"No!");
if((x>>(mid+1)).none()) r=mid;
else l=mid+1;
}return l;
} inline void Cout(bs x) {
int le = highbit(x);
for(int i = le;i >= 0;i --) {
putchar(x.test(i) ? '1':'0');
}return ;
} struct XXJ{
bs F[1202];
int cnt;
XXJ(){cnt = 0;}
inline void ins(bs x) {
while(x.any()) {
int j = highbit(x);
if(F[j].none()) {
F[j] = x;
cnt ++;
return ;
}
x ^= F[j];
}
}
}xxj[35]; vector<bs> tre[MAXN<<2];
inline void addtree(int a,int l,int r,int al,int ar,bs y) {
if(al > r || ar < l) return ;
if(al >= l && ar <= r) {
tre[a].push_back(y);
return ;
}
int mid = al + ar >> 1;
addtree(a<<1,l,r,al,mid,y);
addtree(a<<1|1,l,r,mid+1,ar,y);
return ;
}
inline void pushdown(int a,int al,int ar,int id) {
for(int i = 0;i < tre[a].size();i ++) {
xxj[id].ins(tre[a][i]);
}
if(al == ar) {
bs as;
for(int i = 1000;i >= 0;i --) {
if(xxj[id].F[i].any() && !as.test(i)) {
as = as ^ xxj[id].F[i];
}
}
ans[al] = as;
return ;
}
xxj[id+1] = xxj[id];
int mid = al + ar >> 1;
pushdown(a<<1,al,mid,id+1);
xxj[id+1] = xxj[id];
pushdown(a<<1|1,mid+1,ar,id+1);
return ;
} inline void dfs(int x,int fa,int ie) {
vis[x] = 1;
d[x] = d[fa] + 1;
fe[x] = ie;
f[x] = fa;
sum[x] = sum[fa] ^ w0[ie];
for(int i = 0;i < g[x].size();i ++) {
if(!vis[g[x][i].v]) {
dfs(g[x][i].v,x,g[x][i].id);
}
else if(g[x][i].v != fa) {
xxj[0].ins(sum[x] ^ w0[g[x][i].id] ^ sum[g[x][i].v]);
}
}
}
signed main() {
string ss;
n = read(); m = read(); k = read();
for(int i = 1;i <= m;i ++) {
s = read(); o = read();
cin>>ss;
bs ww(ss);
w0[i] = ww;
g[s].push_back(it(o,i));
g[o].push_back(it(s,i));
}
dfs(1,0,0);
int kk = 0;
for(int i = 1;i <= k;i ++) {
char S[15];
scanf("%s",S + 1);
if(S[1] == 'A') {
kk ++;
u[kk] = s = read(); v[kk] = o = read();
cin>>ss;
lc[kk] = sum[s] ^ sum[o];
bs ww(ss);
w[kk] = ww;
tm[kk] = i;
}
else if(S[2] == 'h') {
s = read();
cin>>ss;
bs ww(ss);
addtree(1,tm[s],i-1,1,k,lc[s] ^ w[s]);
w[s] = ww;
tm[s] = i;
}
else {
s = read();
addtree(1,tm[s],i-1,1,k,lc[s] ^ w[s]);
tm[s] = 0;
}
}
for(int i = 1;i <= kk;i ++) {
if(tm[i]) {
addtree(1,tm[i],k,1,k,lc[i] ^ w[i]);
tm[i] = 0;
}
}
if(1) {
bs as;
for(int i = 1000;i >= 0;i --) {
if(xxj[0].F[i].any() && !as.test(i)) {
as = as ^ xxj[0].F[i];
}
}
Cout(as);ENDL;
}
if(k < 1) return 0;
pushdown(1,1,k,0);
for(int i = 1;i <= k;i ++) {
Cout(ans[i]);ENDL;
}
return 0;
}

LOJ2312 LUOGU-P3733「HAOI2017」八纵八横 (异或线性基、生成树、线段树分治)的更多相关文章

  1. 【Luogu3733】[HAOI2017]八纵八横(线性基,线段树分治)

    [Luogu3733][HAOI2017]八纵八横(线性基,线段树分治) 题面 洛谷 题解 看到求异或最大值显然就是线性基了,所以只需要把所有环给找出来丢进线性基里就行了. 然后线性基不资磁撤销?线段 ...

  2. LOJ 2312(洛谷 3733) 「HAOI2017」八纵八横——线段树分治+线性基+bitset

    题目:https://loj.ac/problem/2312 https://www.luogu.org/problemnew/show/P3733 原本以为要线段树分治+LCT,查了查发现环上的值直 ...

  3. 【LibreOJ】#6396. 「THUPC2018」弗雷兹的玩具商店 / Toyshop 线段树+完全背包

    [题目]#6396. 「THUPC2018」弗雷兹的玩具商店 / Toyshop [题意]给定一个长度为n的物品序列,每个物品有价值.不超过m的重量.要求支持以下三种操作:1.物品价值区间加减,2.物 ...

  4. loj#2312. 「HAOI2017」八纵八横(线性基 线段树分治)

    题意 题目链接 Sol 线性基+线段树分治板子题.. 调起来有点自闭.. #include<bits/stdc++.h> #define fi first #define se secon ...

  5. LOJ 121 「离线可过」动态图连通性——LCT维护删除时间最大生成树 / 线段树分治

    题目:https://loj.ac/problem/121 离线,LCT维护删除时间最大生成树即可.注意没有被删的边的删除时间是 m+1 . 回收删掉的边的节点的话,空间就可以只开 n*2 了. #i ...

  6. 「LuoguP3865」 【模板】ST表 (线段树

    题目背景 这是一道ST表经典题——静态区间最大值 请注意最大数据时限只有0.8s,数据强度不低,请务必保证你的每次查询复杂度为 O(1) 题目描述 给定一个长度为 N 的数列,和 M 次询问,求出每一 ...

  7. 「BZOJ1537」Aut – The Bus(变形Dp+线段树/树状数组 最优值维护)

    网格图给予我的第一反应就是一个状态 f[i][j] 表示走到第 (i,j) 这个位置的最大价值. 由于只能往下或往右走转移就变得显然了: f[i][j]=max{f[i-1][j], f[i][j-1 ...

  8. LOJ 3094 「BJOI2019」删数——角标偏移的线段树

    题目:https://loj.ac/problem/3094 弱化版是 AGC017C . 用线段树维护那个题里的序列即可. 对应关系大概是: 真实值的范围是 [ 1-m , n+m ] :考虑设偏移 ...

  9. 「luogu4462」[CQOI2018] 异或序列

    「luogu4462」[CQOI2018]异或序列 一句话题意 输入 \(n\) 个数,给定\(k\),共 \(m\) 组询问,输出第 \(i\) 组询问 \(l_i\) \(r_i\) 中有多少个连 ...

随机推荐

  1. 超详细干货!Docker+PXC+Haproxy搭建高可用强一致性的MySQL集群

    前言 干货又来了,全程无废话,可先看目录了解. MySQL搭建集群最常见的是binlog方式,但还有一种方式是强一致性的,能保证集群节点的数据一定能够同步成功,这种方式就是pxc,本篇就使用图文方式一 ...

  2. 陈宏智:字节跳动自研万亿级图数据库ByteGraph及其应用与挑战

    导读: 作为一种基础的数据结构,图数据的应用场景无处不在,如社交.风控.搜广推.生物信息学中的蛋白质分析等.如何高效地对海量的图数据进行存储.查询.计算及分析,是当前业界热门的方向.本文将介绍字节跳动 ...

  3. MAUI模板项目闪退问题

    MAUI模板项目闪退问题 在MAUI最初发布的时候就曾创建过几个模板项目进行体验过,没遇到什么坑.由于最近需要开发针对餐饮行业的收银机(安卓系统)开发一款应用,这种收银机一般配置不咋滴,系统版本和性能 ...

  4. pytorch自定义模型时实现父类构造函数的问题

    问题 有的类继承nn.Module在init函数里面是super(类名, self).init():但是有的里面就是super().init() exp: · 解答: python2与python3的 ...

  5. mysql5.7安装要踩的坑

    因为官网下载的是绿色版,所以要做一些配置 1.在mysql根目录新增data文件夹和my.ini文件 my.ini文件内容 [mysql]# 设置mysql客户端默认字符集default-charac ...

  6. SAP Using Text Modules in Adobe Forms

    In this demo we will create an adobe form which displays text in two different languages (English or ...

  7. SAP BDC 调用中 金额格式转换

    在BDC调用中,由于用户设置不同,导致金额.日期等字段的输入格式不正确.此处给出 自创 金额转换FM 并配有 调用方式. function zgm_conver_cuur. *"------ ...

  8. nginx源码层面探究request_time、upstream_response_time、upstream_connect_time与upstream_header_time指标具体含义

    背景概述 最近计划着重分析一下线上各api的HTTP响应耗时情况,检查是否有接口平均耗时.99分位耗时等相关指标过大的情况,了解到nginx统计请求耗时有四个指标:request_time.upstr ...

  9. Win10默认以管理员身份运行cmd命令提示符

    如图所示操作

  10. Windows 远程连接后,自动断开,所有程序都自动关闭(待验证,待更新)

    win+r输入regedit打开注册表编辑SecurityLayer,将值改为2 计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Ter ...