【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横
不知道为什么bzoj没有HAOI2017
题目描述
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最大值。
注意:输出的答案也要以二进制的形式从高位到低位给出。
说明
【数据规模与约定】
令所有的经济因子二进制表示的最多位数为len.数据满足以下表格
数据点 n的规模 m的规模 Q的规模 len的规模 备注
1 <=5 <=8 0 <=31
2 <= 100 =n + 1 0 <= 100
3 <= 100 <= 100 0 <= 100
4 <= 500 <= 500 0 <= 1000
5 <= 100 <= 100 <= 100 <= 200 只存在 Add搡作
6 <= 500 <= 500 <= 200 <= 1000
7 <= 100 <= 100 <= 1000 <= 200
8 <= 500 <= 500 <= 1000 <= 1000
9 <= 500 <= 500 <= 1000 <= 1000
10 <= 500 <= 500 <= 1000 <= 1000
对于所有的数据保证:n,m<=500,Q,len<=1000,1<x,y<n.且Add操作不超过500个.两个城市之间可能有多条高速公路或高铁,高速公路或高铁的两端可能是同一个城市(即 有重边.有自环)。
题目大意
初始给定一张无向连通图,每次操作动态加、删、修改一条边,询问操作后经过根的环最大异或价值,允许离线。
题目分析
首先考虑不修改是个怎么一回事。这个无向连通图的套路参考WC2011 XOR:因为整张图始终保持连通,那么先对原图求一颗生成树,再将所有的环都放在线性基里,答案就是全局线性基的最大值。
现在相当于每条边有各自的存在时间,那么这就符合线段树分治的模型:“在时间轴上,每一个时间点的答案基于若干个给定元素”。
这里有个线段树分治的撤销小问题。最初我还在想线性基怎么撤销,后来发现$Q\log Q$次的分治每次开一个线性基,在过程里下传就可以了。
于是将以上两者相结合就可以了。
打挂的两点:
- 记$tag[x]$为第$x$条插入的边在vector中的位置,$tag[x]$在边change(即再开一条边的时候)和$x$弄混了
- vector里$w$记录的是整个环的异或值,因此要记录环上的那一条非树边来处理change操作
#include<bits/stdc++.h>
typedef std::bitset<> bit;
const int maxn = ;
const int maxm = ;
const int maxq = ;
const int maxOpt = ; struct Opt
{
int l,r;
bit w,rin;
Opt(int a=, int b=, bit c=bit(), bit d=bit()):l(a),r(b),w(c),rin(d) {}
}sv[maxm];
struct Edge
{
int v;
bit w;
Edge(int a=, bit b=bit()):v(a),w(b) {}
}edges[maxm];
struct LinearBasis
{
bit p[];
void insert(bit w)
{
for (int i=, chk=; i>=&&!chk; i--)
if (w[i]){
if (p[i].any()) w ^= p[i];
else p[i] = w, chk = ;
}
}
void query()
{
bit ans = bit();
int pos = ;
for (int i=; i>=; i--)
{
if (ans[i]==) ans ^= p[i];
if (ans[i]&&!pos) pos = i;
}
for (int i=pos; i>=; i--) putchar(ans[i]?'':'');
puts("");
}
};
typedef std::vector<Opt> vec;
int n,m,T,cnt;
int fat[maxn],tag[maxq];
int edgeTot,head[maxn],nxt[maxm];
bit dis[maxn],tmp;
char str[];
vec opt; int read()
{
char ch = getchar();
int num = , fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = -;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
return num*fl;
}
void read(bit &x)
{
char str[];
scanf("%s",str+), x = bit();
for (int i=strlen(str+), j=; i>=; i--)
x[j] = str[i]-'', ++j;
}
int find(int x){return x==fat[x]?x:fat[x]=find(fat[x]);}
void addedge(int u, int v, bit w)
{
edges[++edgeTot] = Edge(v, w), nxt[edgeTot] = head[u], head[u] = edgeTot;
edges[++edgeTot] = Edge(u, w), nxt[edgeTot] = head[v], head[v] = edgeTot;
}
void dfs(int x, int fa, bit c)
{
dis[x] = c;
for (int i=head[x]; i!=-; i=nxt[i])
{
int v = edges[i].v;
if (v!=fa) dfs(v, x, c^edges[i].w);
}
}
void solve(int l, int r, vec opt, LinearBasis bas)
{
vec L,R;
int mid = (l+r)>>;
for (int i=, mx=opt.size(); i<mx; i++)
if (opt[i].l <= l&&r <= opt[i].r) bas.insert(opt[i].w);
else{
if (opt[i].l <= mid) L.push_back(opt[i]);
if (opt[i].r > mid) R.push_back(opt[i]);
}
if (l==r) bas.query();
else solve(l, mid, L, bas), solve(mid+, r, R, bas);
}
int main()
{
memset(head, -, sizeof head);
n = read(), m = read(), T = read();
for (int i=; i<=n; i++) fat[i] = i;
for (int i=,u,v; i<=m; i++)
{
u = read(), v = read(), read(tmp);
if (find(u)!=find(v))
fat[fat[u]] = fat[v], addedge(u, v, tmp);
else sv[++cnt] = Opt(u, v, tmp);
}
dfs(, , bit());
for (int i=; i<=cnt; i++)
opt.push_back(Opt(, T, sv[i].w^dis[sv[i].l]^dis[sv[i].r]));
for (int i=,cnt=,u,v; i<=T; i++)
{
scanf("%s",str);
if (str[]=='A'){
u = read(), v = read(), read(tmp);
opt.push_back(Opt(i, T, dis[u]^dis[v]^tmp, tmp));
tag[++cnt] = opt.size()-;
}else if (str[]=='h'){
u = read(), read(tmp), opt[tag[u]].r = i-;
opt.push_back(Opt(i, T, tmp^opt[tag[u]].rin^opt[tag[u]].w, tmp));
tag[u] = opt.size()-;
}else opt[tag[read()]].r = i-;
}
solve(, T, opt, LinearBasis());
return ;
}
END
【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横的更多相关文章
- BZOJ.4184.shallot(线段树分治 线性基)
BZOJ 裸的线段树分治+线性基,就是跑的巨慢_(:з」∠)_ . 不知道他们都写的什么=-= //41652kb 11920ms #include <map> #include < ...
- $CF938G\ Shortest\ Path\ Queries$ 线段树分治+线性基
正解:线段树分治+线性基 解题报告: 传送门$QwQ$ 考虑如果只有操作3,就这题嘛$QwQ$ 欧克然后现在考虑加上了操作一操作二 于是就线段树分治鸭 首先线段树叶子节点是询问嘛这个不用说$QwQ$. ...
- 【luogu3733】【HAOI2017】 八纵八横 (线段树分治+线性基)
Descroption 原题链接 给你一个\(n\)个点的图,有重边有自环保证连通,最开始有\(m\)条固定的边,要求你支持加边删边改边(均不涉及最初的\(m\)条边),每一次操作都求出图中经过\(1 ...
- LOJ 2312(洛谷 3733) 「HAOI2017」八纵八横——线段树分治+线性基+bitset
题目:https://loj.ac/problem/2312 https://www.luogu.org/problemnew/show/P3733 原本以为要线段树分治+LCT,查了查发现环上的值直 ...
- Codeforces 938G 线段树分治 线性基 可撤销并查集
Codeforces 938G Shortest Path Queries 一张连通图,三种操作 1.给x和y之间加上边权为d的边,保证不会产生重边 2.删除x和y之间的边,保证此边之前存在 3.询问 ...
- BZOJ4184:shallot(线段树分治,线性基)
Description 小苗去市场上买了一捆小葱苗,她突然一时兴起,于是她在每颗小葱苗上写上一个数字,然后把小葱叫过来玩游戏. 每个时刻她会给小葱一颗小葱苗或者是从小葱手里拿走一颗小葱苗,并且 让小葱 ...
- bzoj 4184 shallot——线段树分治+线性基
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4184 本来想了可持久化trie,不过空间是 nlogn (出一个节点的时候把 tot 复原就 ...
- bzoj 4184: shallot (线段树维护线性基)
题面 \(solution:\) 这一题绝对算的上是一道经典的例题,它向我们诠释了一种新的线段树维护方式(神犇可以跳过了).像这一类需要加入又需要维护删除的问题,我们曾经是遇到过的像莫对,线段树... ...
- 2017西安区域赛A / UVALive - 8512 线段树维护线性基合并
题意:给定\(a[1...n]\),\(Q\)次询问求\(A[L...R]\)的异或组合再或上\(K\)的最大值 本题是2017的西安区域赛A题,了解线性基之后你会发现这根本就是套路题.. 只要用线段 ...
随机推荐
- ES6新特性使用小结(五)
十二.class 与 extends ①.类的基本定义和生成实例 { class Parent{ constructor(name='Lain'){ //定义构造函数 this.name = name ...
- Codeforces 140D(贪心)
要点 跟大家打acm的策略一样,为了做更多的题数肯定做最简单的题目,为了罚时更少肯定从易到难做 虽然有个12:00之限不同于往常比赛,但细想还是要从易到难贪:做这些题的总时间肯定是不变的,只是顺序可变 ...
- Codeforces 1152D(dp)
要点 寻找最多边的匹配的结论:贪心地从叶子开始找,最后答案都是奇数层下边的那条边. 设\(dp[i][j]\)表示当前长度为\(i\),平衡度为\(j\),平衡度为(数量减去)数量. 增加左右括号转移 ...
- 使用Zeppelin时出现at org.apache.zeppelin.interpreter.thrift.RemoteInterpreterService$Client.recv_getFormType(RemoteInterpreterService.java:288)错误的解决办法(图文详解)
不多说,直接上干货! 问题详解 org.apache.thrift.TApplicationException: Internal error processing getFormType at or ...
- Error resolving template: template might not exist or might not be accessible是一句缩水报错?
一 thymeleaf在开发的时候本地调试正常,但是在测试环境打成jar包就报这个错误了. 二 template might not exist or might not be accessible ...
- 在MVC中使用dotless后台动态解析LESSCSS的学习笔记
通过学习LessCSS,我们知道,Less是需要通过编译才能生成 .css 文件,主要使用三种方式进行编译: 1)使用第三方编译工具,在项目发布前编译好放在项目中. 2)在浏览器端解析执行,需要引用 ...
- 13.JAVA-包package、import使用
1.包的定义 之前我们学习java时,生成的class文件都是位于当前目录中,假如出现了同名文件,则会出现文件覆盖问题,因此就需要设置不同的目录(定义包),来解决同名文件冲突问题. 并且在大型项目中, ...
- JS判断android ios系统 PC端和移动端
最近公司上线移动端,需要根据不同的系统跳转到不同的产品页面,百度后发现这一段代码很好用,不但可以判断当前是什么系统,还能知道当前浏览器是什么内核,移动端PC端都已测试无问题! var browser ...
- 函数补充:动态参数,函数嵌套,global与nonlocal关键
一丶动态参数 1.*args 位置参数,动态传参 def func(*food): print(food) print(func("米饭","馒头"," ...
- Android 虚拟导航挡住应用底部解决方案(屏幕底部的三个按键)
我在华为P6测试机上测试,发现底部的三个虚拟按钮遮挡了我的应用.类似效果如:https://www.zhihu.com/question/35292413#answer-28473700 解决方案 在 ...