[BZOJ 2322][BeiJing2011]梦想封印
梦想封印
题意
原题面:
Problem 2322. -- [BeiJing2011]梦想封印
2322: [BeiJing2011]梦想封印
Time Limit: 20 Sec Memory Limit: 128 MB
Submit: 607 Solved: 240
[Submit][Status][Discuss]
Description
渐渐地,Magic Land上的人们对那座岛屿上的各种现象有了深入的了解。
为了分析一种奇特的称为梦想封印(Fantasy Seal)的特技,需要引入如下的概念:
每一位魔法的使用者都有一个“魔法脉络”,它决定了可以使用的魔法的种类。
一般地,一个“魔法脉络”可以看作一个无向图,有N个结点及M条边,将结点编号为1~N,其中有一个结点是特殊的,称为核心(Kernel),记作1号结点。每一条边有一个固有(即生成之后再也不会发生变化的)权值,是一个不超过U的自然数。
每一次魔法驱动,可看作是由核心(Kernel)出发的一条有限长的道路(Walk),可以经过一条边多次,所驱动的魔法类型由以下方式给出:
将经过的每一条边的权值异或(xor)起来,得到s。
如果s是0,则驱动失败,否则将驱动编号为s的魔法(每一个正整数编号对应了唯一一个魔法)。
需要注意的是,如果经过了一条边多次,则每一次都要计入s中。
这样,魔法脉络决定了可使用魔法的类型,当然,由于魔法与其编号之间的关系尚未得到很好的认知,此时人们仅仅关注可使用魔法的种类数。
梦想封印可以看作是对“魔法脉络”的破坏:
该特技作用的结果是,“魔法脉络”中的一些边逐次地消失。
我们记总共消失了Q条边,按顺序依次为Dis1、Dis2、……、DisQ。
给定了以上信息,你要计算的是梦想封印作用过程中的效果,这可以用Q+1个自然数来描述:
Ans0为初始时可以使用魔法的数量。
Ans1为Dis1被破坏(即边被删去)后可以使用魔法的数量。
Ans2为Dis1及Dis2均被破坏后可使用魔法的数量。
……
AnsQ为Dis1、Dis2、……、DisQ全部被破坏后可以使用魔法的数量。
Input
第一行包含三个正整数N、M、Q。
接下来的M行,每行包含3个整数,Ai、Bi、Wi,表示一条权为Wi的与结点Ai、Bi关联的无向边,其中Wi是不超过U的自然数。
接下来Q行,每行一个整数:Disi。
Output
一共包Q+1行,依次为Ans0、Ans1、……、AnsQ。
Sample Input
【输入样例1】
3 3 2
1 2 1
2 3 2
3 1 4
1
3
【输入样例2】
5 7 7
1 2 1
1 3 1
2 4 2
2 5 2
4 5 4
5 3 9
4 3 1
7
6
5
4
3
2
1
Sample Output
【输出样例1】
5
2
0
【样例1解释】
初始时可使用编号为1、3、4、6、7的魔法。
在删去第1条边(连结1、2结点的边)后,可使用4和6号魔法。
第3条边(连结第1、3结点的边)也被删去后,核心(Kernel)即结点1孤立,易知此时无法使用魔法。
【输出样例2】
15
11
5
2
2
1
1
0
HINT
【数据规模和约定】
所有数据保证该无向图不含重边、自环。所有数据保证不会有一条边被删除多次,即对于不同i和j,有Disi≠Disj
30%的数据中N ≤ 50,M ≤ 50,Q ≤50,U≤100;
60%的数据中N ≤ 300,M ≤ 300,Q ≤50,U≤10^9;
80%的数据中N ≤ 300,M ≤ 5000,Q ≤5000,U≤10^18;
100%的数据中N ≤ 5000,M ≤ 20000,Q ≤20000,U≤10^18;
Source
给定一张无向带权有根图, 求从根出发的任意一条路径上的边的异或和的种类数量.
题解
果然车万题不少都是高端题
首先如果这题是树的话其实就等价于求根到所有结点的异或和. 因为跑到其他地方必定要跑回来于是就又把原来的贡献异或掉了
所以问题在于环.
考虑一个环会产生什么高端操作? 沿着环走一圈回到原点, 然后总贡献变了.
也就是说对于环我们可以任意选择要不要加入路径贡献中. (走过去再走回来, 沿途的贡献便被消去了)
对于环的情况我们求一遍线性基那么对于种类的贡献就是 \(2^k\) 了
然后考虑剩下的简单路径. (作出贡献的必然是简单路径. 重复的会抵消. 于是等价于从根出发到所有其他结点的路径)
注意到只有DFS树上的简单路径是有用的(如果有多种方案可以从根到达某个点, 那么另一条路径的贡献可以通过树上路径异或上一个环得到). 于是有用的路径只有 \(O(V)\) 条.
用环的线性基消这些简单路径, 剩下的杂值就是无法被表出的部分, 也就是这个简单路径的特殊部分. 如果两个路径的特征值相等, 那么其中一个路径选一些环后得到的值必然也可以在另一条路径的基础上选一些环表出. 那么它们对总方案作出的贡献是重复的. 需要去重.
所以把这些值丢到 set 里就好了
最后的答案就是 \(p\times 2^k-1\). \(p\) 是 set 的大小, \(k\) 是线性基的大小. \(-1\) 是因为 \(0\) 的情况不做贡献.
然而上面解决的是静态问题
动态删边果断离线然后变成加边.
考虑加入一条边后有什么高端操作. 假设加入的边端点为 \(u,v\).
- 如果 \(u\) 和 \(v\) 都不与根连通, 则这条边对答案没有贡献, 先扔着就好了
- 如果 \(u\) 和 \(v\) 中有一个与根联通, 那么 \(v\) 所在的整个联通块都可以作出贡献,
DFS计算这些贡献.- 首先计算根到这个点的树上路径的异或和, 用线性基消一下丢到
set里 - 如果遇到了环, 把它插入线性基. 然后用新的线性基更新整个
set.
- 首先计算根到这个点的树上路径的异或和, 用线性基消一下丢到
- 如果 \(u\) 和 \(v\) 都与根联通, 则一定有一个环出现. 注意到只要把其中一个包含边 \((u,v)\) 的环丢进线性基就可以了, 其他的新环都可以通过原来已经存在的环异或上这个环构造出来. 那么我们直接选最容易搞的环, 把根到 \(u\) 的异或和异或上根到 \(v\) 的异或和最后异或上边 \((u,v)\) 的值就可以得到一个环的值了, 插进线性基即可.
预处理也可以参考上面的策略用一次 DFS 解决.
参考代码
#include <bits/stdc++.h>
const int MAXV=5010;
const int MAXE=1e5+10;
typedef long long intEx;
struct Edge{
int from;
int to;
intEx val;
Edge* next;
};
Edge E[MAXE];
Edge Ex[MAXE];
Edge* head[MAXV];
Edge* top=E;
int v;
int e;
int q;
int brk[MAXE];
int pos[MAXE];
int prt[MAXV];
bool vis[MAXV];
intEx sum[MAXV];
intEx ans[MAXE];
std::set<intEx> path;
std::vector<intEx> base;
void DFS(int);
inline intEx Elim(intEx);
inline intEx Insert(intEx);
inline void AddCycle(intEx);
inline void Insert(int,int,intEx);
int main(){
scanf("%d%d%d",&v,&e,&q);
for(int i=1;i<=e;i++)
scanf("%d%d%lld",&Ex[i].from,&Ex[i].to,&Ex[i].val);
for(int i=1;i<=q;i++){
scanf("%d",pos+i);
brk[pos[i]]=i;
}
for(int i=1;i<=e;i++){
if(brk[i]==0){
Insert(Ex[i].from,Ex[i].to,Ex[i].val);
Insert(Ex[i].to,Ex[i].from,Ex[i].val);
}
}
DFS(1);
ans[q]=(intEx(path.size())<<base.size())-1;
for(int i=q;i>0;i--){
Edge* k=Ex+pos[i];
Insert(k->from,k->to,k->val);
Insert(k->to,k->from,k->val);
int cnt=vis[k->from]+vis[k->to];
if(cnt==2)
AddCycle(sum[k->from]^sum[k->to]^k->val);
else if(cnt==1){
if(vis[k->from]){
sum[k->to]=sum[k->from]^k->val;
DFS(k->to);
}
else{
sum[k->from]=sum[k->to]^k->val;
DFS(k->from);
}
}
ans[i-1]=(intEx(path.size())<<base.size())-1;
}
for(int i=0;i<=q;i++)
printf("%lld\n",ans[i]);
return 0;
}
void AddCycle(intEx val){
if((val=Insert(val))){
std::set<intEx> tmp;
for(auto i:path)
tmp.insert(std::min(i,i^val));
std::swap(tmp,path);
}
}
void DFS(int root){
vis[root]=true;
path.insert(Elim(sum[root]));
for(Edge* i=head[root];i!=NULL;i=i->next){
if(vis[i->to])
AddCycle(sum[root]^sum[i->to]^i->val);
else{
sum[i->to]=sum[root]^i->val;
DFS(i->to);
}
}
}
inline intEx Elim(intEx x){
for(auto i:base)
x=std::min(x,x^i);
return x;
}
inline intEx Insert(intEx x){
x=Elim(x);
if(x!=0)
base.push_back(x);
return x;
}
inline void Insert(int from,int to,intEx val){
top->from=from;
top->to=to;
top->val=val;
top->next=head[from];
head[from]=top++;
}

[BZOJ 2322][BeiJing2011]梦想封印的更多相关文章
- 【BZOJ2322】[BeiJing2011]梦想封印 高斯消元求线性基+DFS+set
[BZOJ2322][BeiJing2011]梦想封印 Description 渐渐地,Magic Land上的人们对那座岛屿上的各种现象有了深入的了解. 为了分析一种奇特的称为梦想封印(Fantas ...
- BZOJ2322: [BeiJing2011]梦想封印
Description 渐渐地,Magic Land上的人们对那座岛屿上的各种现象有了深入的了解. 为了分析一种奇特的称为梦想封印(Fantasy Seal)的特技,需要引入如下的概念: 每一位魔法的 ...
- 【线性基】bzoj2322: [BeiJing2011]梦想封印
线性基的思维题+图常见套路 Description 渐渐地,Magic Land上的人们对那座岛屿上的各种现象有了深入的了解. 为了分析一种奇特的称为梦想封印(Fantasy Seal)的特技,需要引 ...
- 【BZOJ 2322】[BeiJing2011]梦想封印 利用"环基"+线性基特征值
很容易想到离线加边并且把环和链拆开搞(就是对于每个终点求出起点到他的路径(其实就是dfs树),然后bzoj2115),而且维护也很简单,然而我们发现不同的终点可能得到相同的值,这就是我们遇到的最大的问 ...
- BZOJ2322 [BeiJing2011]梦想封印 【set + 线性基】
题目链接 BZOJ2322 题解 鉴于BZOJ2115,要完成此题,就简单得多了 对图做一遍\(dfs\),形成\(dfs\)树,从根到每个点的路径形成一个权值,而每个返祖边形成一个环 我们从根出发去 ...
- BZOJ 2462: [BeiJing2011]矩阵模板
2462: [BeiJing2011]矩阵模板 Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 915 Solved: 432[Submit][Stat ...
- 【贪心】Bzoj 2457:[BeiJing2011]双端队列
2457: [BeiJing2011]双端队列 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 209 Solved: 95[Submit][Stat ...
- BZOJ 2460: [BeiJing2011]元素
2460: [BeiJing2011]元素 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 878 Solved: 470[Submit][Statu ...
- BZOJ:2460[BeiJing2011]元素 (异或基+贪心)
2460: [BeiJing2011]元素 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2910 Solved: 1535 题目链接:https: ...
随机推荐
- assert函数的用法
assert这个函数在php语言中是用来判断一个表达式是否成立.返回true or false; 例如: <?php $s = 123; assert("is_int($s)" ...
- Java 动态代理机制分析及扩展--转
http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/#icomments http://www.ibm.com/developerworks/c ...
- spark2.4+elasticsearch6.1.1搭建一个推荐系统
目录 整体框架 安装相关的组件 elasticsearch安装 spark安装 下载es-hadoop中间件 安装计算向量相似度的elasticsearch插件 运行 结果展示 参考博客 本博文详细记 ...
- JD上市前内情:李彦宏雷军柳传志拷问刘强东
这篇文章是京东上市前夕,在某个会议上刘强东与柳传志.李彦宏.雷军等大佬们的闭门交流实录,由于当时京东正值上市敏感期,文章没有被发出来,现在京东上市了,我想,大家可以看看几位商界大佬对刘强东的“犀利拷问 ...
- [C#]LockBits使用笔记
昨天想基于一张图片做个手机锁屏来着,原图如下:主要是嫌白底太丑了,一开始是想画图工具直接油漆桶伺候,然而一浇上去就发现问题了,变成了这样:看来得手工处理一下把底色统一了,原图分辨率挺高的,SetPix ...
- [LeetCode]Longest Substring Without Repeating Characters题解
Longest Substring Without Repeating Characters: Given a string, find the length of the longest subst ...
- poj 2796 Feel Good 单调队列
Feel Good Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 8753 Accepted: 2367 Case Ti ...
- C# 简单的loading提示控件
自己画一个转圈圈的控件 using System; using System.Collections.Generic; using System.ComponentModel; using Syste ...
- shutil的一些基本用法
import shutil import time import tarfile # 将文件内容拷贝到另一个文件中 shutil.copyfileobj(open('a1', 'r'), open(' ...
- Luogu 4240:毒瘤之神的考验
传送门 Sol 分开考虑 \(\varphi(ij)\) 中 \(ij\) 的质因子 那么 \[\varphi(ij)=\frac{\varphi(i)\varphi(j)gcd(i,j)}{\var ...