不知道为什么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]八纵八横的更多相关文章

  1. BZOJ.4184.shallot(线段树分治 线性基)

    BZOJ 裸的线段树分治+线性基,就是跑的巨慢_(:з」∠)_ . 不知道他们都写的什么=-= //41652kb 11920ms #include <map> #include < ...

  2. $CF938G\ Shortest\ Path\ Queries$ 线段树分治+线性基

    正解:线段树分治+线性基 解题报告: 传送门$QwQ$ 考虑如果只有操作3,就这题嘛$QwQ$ 欧克然后现在考虑加上了操作一操作二 于是就线段树分治鸭 首先线段树叶子节点是询问嘛这个不用说$QwQ$. ...

  3. 【luogu3733】【HAOI2017】 八纵八横 (线段树分治+线性基)

    Descroption 原题链接 给你一个\(n\)个点的图,有重边有自环保证连通,最开始有\(m\)条固定的边,要求你支持加边删边改边(均不涉及最初的\(m\)条边),每一次操作都求出图中经过\(1 ...

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

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

  5. Codeforces 938G 线段树分治 线性基 可撤销并查集

    Codeforces 938G Shortest Path Queries 一张连通图,三种操作 1.给x和y之间加上边权为d的边,保证不会产生重边 2.删除x和y之间的边,保证此边之前存在 3.询问 ...

  6. BZOJ4184:shallot(线段树分治,线性基)

    Description 小苗去市场上买了一捆小葱苗,她突然一时兴起,于是她在每颗小葱苗上写上一个数字,然后把小葱叫过来玩游戏. 每个时刻她会给小葱一颗小葱苗或者是从小葱手里拿走一颗小葱苗,并且 让小葱 ...

  7. bzoj 4184 shallot——线段树分治+线性基

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4184 本来想了可持久化trie,不过空间是 nlogn (出一个节点的时候把 tot 复原就 ...

  8. bzoj 4184: shallot (线段树维护线性基)

    题面 \(solution:\) 这一题绝对算的上是一道经典的例题,它向我们诠释了一种新的线段树维护方式(神犇可以跳过了).像这一类需要加入又需要维护删除的问题,我们曾经是遇到过的像莫对,线段树... ...

  9. 2017西安区域赛A / UVALive - 8512 线段树维护线性基合并

    题意:给定\(a[1...n]\),\(Q\)次询问求\(A[L...R]\)的异或组合再或上\(K\)的最大值 本题是2017的西安区域赛A题,了解线性基之后你会发现这根本就是套路题.. 只要用线段 ...

随机推荐

  1. Programming Ruby 阅读笔记

    在Ruby中,通过调用构造函数(constructor)来创建对象 song1=Song.new("Ruby") Ruby对单引号串处理的很少,除了极少的一些例外,键入到字符串字面 ...

  2. 【NOI2012】迷失游乐园

    题目链接:迷失游乐园(BZOJ)  迷失游乐园(Luogu) 独立完成的题,写一发题解纪念一波~ 模拟完样例大概可以知道是道树形DP了. 观察数据范围,发现是基环树,至少会有一个环. 先从树的部分开始 ...

  3. MFS安装

    mfs github地址:https://github.com/moosefs/moosefs 一. 准备 1. 名字解释 Mfsmaster 元数据 Metalogger 元数据备份,用于恢复数据( ...

  4. PHP 扩展篇 _ 持续更新

    记住这个网站:http://pecl.php.net/ PHP-Redis扩展更新时间:2019/05/06 PHP安装Redis 1:下载目前最新版的redis插件 wget http://pecl ...

  5. JQuery扩展和事件

    一.jQuery事件 常用事件 blur([[data],fn]) 失去焦点 focus([[data],fn]) 获取焦点( 搜索框例子) change([[data],fn]) 当select下拉 ...

  6. 洛谷P4719 【模板】动态dp

    https://www.luogu.org/problemnew/show/P4719 大概就是一条链一条链的处理(“链”在这里指重链),对于每一条链,对于其上每一个点,先算出它自身和所有轻儿子的贡献 ...

  7. openstack安装newton版本创建虚拟机(五)

    一.创建网络: 1.在控制节点上创建一个单一扁平网络(名字:flat),网络类型为flat,网络适共享的(share),网络提供者:physnet1,它是和eth0关联起来的 [root@linux- ...

  8. PS高级特训班 百度云资源(价值2180元)

    课程目录:   第1章第一期1第一节 火焰拳头1:12:252第二节 荷叶合成00:05:143第三节 新年巨惠海报(一)1:00:374第四节 新年巨惠海报(二)1:05:345第五节 美食印刷品1 ...

  9. 传智播客C++

    轻松入门实战应用传智播客C++学院就业班第一阶段C提高课程 传智播客C提高讲义 传智扫地僧 1程序内存模型 1.1就业班引言 1.1.1问题引出 企业需要能干活的人  C学到什么程度可以找工作  ...

  10. P4868 天天和不可描述

    http://www.tyvj.cn/p/4868 思路: 本想用站做的,但发现要用很多站同时做,还要来回倒. 我怕超时,所以换了种做法. 因为每遇到一次括号都要把输出方向改变,而括号是成对存在的,所 ...