题目:

洛谷4219

分析:

很明显,查询的是删掉某条边后两端点所在连通块大小的乘积。

有加边和删边,想到LCT。但是我不会用LCT查连通块大小啊。果断弃了

有加边和删边,还跟连通性有关,于是开始yy线段树分治做法(不知道线段树分治?推荐一个伪模板题BZOJ4025二分图事实上这个链接是指向我的博客的)。把每次操作(加边或查询)看做一个时刻,一条边存在的区间就是它加入后没有被查询的时间区间的并。于是用可撤销并查集维护一下连通块大小即可。

代码:

#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <map>
#include <cassert>
#undef i
#undef j
#undef k
#undef min
#undef max
#undef true
#undef false
#undef swap
#undef sort
#undef if
#undef for
#undef while
#undef printf
#undef scanf
#undef putchar
#undef getchar
#define _ 0
using namespace std; namespace zyt
{
template<typename T>
inline bool read(T &x)
{
char c;
bool f = false;
x = 0;
do
c = getchar();
while (c != EOF && c != '-' && !isdigit(c));
if (c == EOF)
return false;
if (c == '-')
f = true, c = getchar();
do
x = x * 10 + c - '0', c = getchar();
while (isdigit(c));
if (f)
x = -x;
return true;
}
inline bool read(char &c)
{
do
c = getchar();
while (c != EOF && !isgraph(c));
return c != EOF;
}
template<typename T>
inline void write(T x)
{
static char buf[20];
char *pos = buf;
if (x < 0)
putchar('-'), x = -x;
do
*pos++ = x % 10 + '0';
while (x /= 10);
while (pos > buf)
putchar(*--pos);
}
typedef long long ll;
const int N = 1e5 + 10, B = 17, QUERY = 0, ADD = 1;
int n, q;
ll ans[N];
struct node
{
bool type;
int x, y;
}arr[N];
namespace UFS
{
int fa[N], rk[N], size[N], top;
struct node
{
int x, y, fax, rky, sizey;
}stack[N];
void init(const int n)
{
for (int i = 1; i <= n; i++)
fa[i] = i, rk[i] = size[i] = 1;
}
int f(const int u)
{
return fa[u] == u ? u : f(fa[u]);
}
bool merge(const int u, const int v)
{
int x = f(u), y = f(v);
if (x == y)
return false;
if (rk[x] > rk[y])
swap(x, y);
stack[top++] = (node){x, y, fa[x], rk[y], size[y]};
fa[x] = y, size[y] += size[x];
if (rk[x] == rk[y])
++rk[y];
return true;
}
int query(const int u)
{
assert(f(u) < N);
return size[f(u)];
}
void undo(const int bck)
{
while (top > bck)
{
--top;
int x = stack[top].x, y = stack[top].y;
assert(x < N && y < N);
fa[x] = stack[top].fax;
rk[y] = stack[top].rky;
size[y] = stack[top].sizey;
}
}
}
namespace Segment_Tree
{
struct edge
{
int x, y, next;
}e[N * (B + 1)];
int head[1 << (B + 1) | 11], ecnt;
inline void init()
{
memset(head, -1, sizeof(head));
}
inline void add(const int a, const int b, const int c)
{
e[ecnt] = (edge){b, c, head[a]}, head[a] = ecnt++;
}
inline void insert(const int rot, const int lt, const int rt, const int ls, const int rs, const int x, const int y)
{
if (ls <= lt && rt <= rs)
{
add(rot, x, y);
return;
}
int mid = (lt + rt) >> 1;
if (ls <= mid)
insert(rot << 1, lt, mid, ls, rs, x, y);
if (rs > mid)
insert(rot << 1 | 1, mid + 1, rt, ls, rs, x, y);
}
inline void solve(const int rot, const int lt, const int rt)
{
int bck = UFS::top;
for (int i = head[rot]; ~i; i = e[i].next)
UFS::merge(e[i].x, e[i].y);
if (lt == rt)
{
if (arr[lt].type == QUERY)
ans[lt] = (ll)UFS::query(arr[lt].x) * UFS::query(arr[lt].y);
UFS::undo(bck);
return;
}
int mid = (lt + rt) >> 1;
solve(rot << 1, lt, mid);
solve(rot << 1 | 1, mid + 1, rt);
UFS::undo(bck);
}
}
map<pair<int, int>, int> lastins;
int work()
{
read(n), read(q);
UFS::init(n);
Segment_Tree::init();
for (int i = 1; i <= q; i++)
{
char opt;
read(opt), read(arr[i].x), read(arr[i].y);
if (arr[i].x > arr[i].y)
swap(arr[i].x, arr[i].y);
arr[i].type = (opt == 'Q' ? QUERY : ADD);
pair<int, int> p = make_pair(arr[i].x, arr[i].y);
if (arr[i].type == ADD)
lastins[p] = i;
else
{
Segment_Tree::insert(1, 1, q, lastins[p], i - 1, p.first, p.second);
lastins[p] = i + 1;
}
}
for (map<pair<int, int>, int>::iterator it = lastins.begin(); it != lastins.end(); it++)
if (it->second <= q)
Segment_Tree::insert(1, 1, q, it->second, q, it->first.first, it->first.second);
Segment_Tree::solve(1, 1, q);
for (int i = 1; i <= q; i++)
if (arr[i].type == QUERY)
write(ans[i]), putchar('\n');
return (0^_^0);
}
}
int main()
{
return zyt::work();
}

【洛谷4219】[BJOI2014]大融合(线段树分治)的更多相关文章

  1. 洛谷4219 BJOI2014大融合(LCT维护子树信息)

    QWQ 这个题目是LCT维护子树信息的经典应用 根据题目信息来看,对于一个这条边的两个端点各自的\(size\)乘起来,不过这个应该算呢? 我们可以考虑在LCT上多维护一个\(xv[i]\)表示\(i ...

  2. 洛谷 P4219 [BJOI2014]大融合 解题报告

    P4219 [BJOI2014]大融合 题目描述 小强要在\(N\)个孤立的星球上建立起一套通信系统.这套通信系统就是连接\(N\)个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的 ...

  3. 洛谷P4219 - [BJOI2014]大融合

    Portal Description 初始有\(n(n\leq10^5)\)个孤立的点,进行\(Q(Q\leq10^5)\)次操作: 连接边\((u,v)\),保证\(u,v\)不连通. 询问有多少条 ...

  4. 洛谷 P4219 [BJOI2014]大融合

    查询,就相当于先删去这条边,然后查询边的两个端点所在连通块大小,乘起来得到答案,然后再把边加回去 可以用线段树分治做 #pragma GCC optimize("Ofast") # ...

  5. 洛谷 P2147 [SDOI2008]洞穴勘测 (线段树分治)

    题目链接 题解 早就想写线段树分治的题了. 对于每条边,它存在于一段时间 我们按时间来搞 我们可把一条边看做一条线段 我们可以模拟线段树操作,不断分治下去 把覆盖\(l-r\)这段时间的线段筛选出来, ...

  6. 洛谷P4219 [BJOI2014]大融合(LCT,Splay)

    LCT维护子树信息的思路总结与其它问题详见我的LCT总结 思路分析 动态连边,LCT题目跑不了了.然而这题又有点奇特的地方. 我们分析一下,查询操作就是要让我们求出砍断这条边后,x和y各自子树大小的乘 ...

  7. 洛谷P4219 [BJOI2014]大融合(LCT)

    LCT维护子树信息的思路总结与其它问题详见我的LCT总结 思路分析 动态连边,LCT题目跑不了了.然而这题又有点奇特的地方. 我们分析一下,查询操作就是要让我们求出砍断这条边后,x和y各自子树大小的乘 ...

  8. 洛谷 P3373 【模板】线段树 2

    洛谷 P3373 [模板]线段树 2 洛谷传送门 题目描述 如题,已知一个数列,你需要进行下面三种操作: 将某区间每一个数乘上 xx 将某区间每一个数加上 xx 求出某区间每一个数的和 输入格式 第一 ...

  9. 【BZOJ-4530】大融合 线段树合并

    4530: [Bjoi2014]大融合 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 280  Solved: 167[Submit][Status] ...

  10. 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块

    !!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...

随机推荐

  1. config对象的使用及常用方法

    config对象的使用及常用方法 制作人:全心全意 config对象主要用于取得服务器的配置信息.通过pageContext对象的getServletConfig()方法可以获取一个config对象. ...

  2. MySQL Insert数据量过大导致报错 MySQL server has gone away

    接手了同事的项目,其中有一个功能是保存邮件模板(包含图片),同事之前的做法是把图片进行base64编码然后存在mysql数据库中(字段类型为mediumtext)然后保存三张图片(大概400k)的时候 ...

  3. hdu 1754 I Hate It(线段树水题)

    >>点击进入原题测试<< 思路:线段树水题,可以手敲 #include<string> #include<iostream> #include<a ...

  4. Codeforces 121A Lucky Sum

    Lucky Sum Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Origi ...

  5. 史上超全面的Neo4j使用指南

    Create by yster@foxmail.com 2018-7-10 我的博客:https://blog.csdn.net/yueshutong123 W3Cschool文档:https://w ...

  6. B树、B-树、B+树、B*树介绍,和B+树更适合做文件索引的原因

    今天看数据库,书中提到:由于索引是采用 B 树结构存储的,所以对应的索引项并不会被删除,经过一段时间的增删改操作后,数据库中就会出现大量的存储碎片, 这和磁盘碎片.内存碎片产生原理是类似的,这些存储碎 ...

  7. 【CV论文阅读】Rank Pooling for Action Recognition

    这是期刊论文的版本,不是会议论文的版本.看了论文之后,只能说,太TM聪明了.膜拜~~ 视频的表示方法有很多,一般是把它看作帧的序列.论文提出一种新的方法去表示视频,用ranking function的 ...

  8. Linux网络编程:UDP Socket编程范例

    TCP协议提供的是一种可靠的,复杂的,面向连接的数据流(SOCK_STREAM)传输服务,它通过三段式握手过程建立连接.TCP有一种"重传确认"机制,即接收端收到数据后要发出一个肯 ...

  9. 国内APP漏洞扫描收费情况调查

    概述 上一次分享了应用加固的评测后,很多人想看看漏洞扫描相关的对比数据.其实在选择市面上这些移动安全类的产品时,经常为各种复杂的数据而感到疑惑,不知道怎么来评判各自的性能以及价格,从而选择出一款性价比 ...

  10. javascript 变量声明 和 作用域

    变量的声明 1.变量声明具有提升机制,Javascript在执行时,会把所有的声明都提升到当前作用域前面. 先看一下下面的例子: (function(){ alert(b)//b is not def ...