题意

\(n\)个点,维护两个森林,这里\(A,B\)两个森林对应的点都是一样的,相当于对两个森林操作都会影响这\(n\)个点

开始森林里的树都是一个点,\(A,B\)支持合并(但树结构互不影响),\(A\)支持树赋\(0\),\(B\)支持树加值

做法

\(A,B\)分开做,每次合并新建一个虚点,这样相当于把\(n\)个点拍扁了,就比较好维护点集的操作

求出对每次查询最近的一次赋\(0\)操作,然后再在这个区间里算\(B\)修改对该点的贡献

将操作离线下来放在树上就可以做了

有个小\(trick\)就是用树状数组倍增一下求最近的那次赋\(0\)操作

Code(jly)

#include <bits/stdc++.h>
using namespace std;
constexpr int N = 500000;
struct Tree {
int n;
vector<int> parent, lc, rc, id;
vector<vector<int>> mod;
Tree(int n) {
parent.assign(2 * n - 1, -1);
lc.assign(2 * n - 1, -1);
rc.assign(2 * n - 1, -1);
id.resize(n);
iota(id.begin(), id.end(), 0);
mod.resize(2 * n - 1);
}
};
long long fen[N + 1];
void add(int x, int y) {
for (int i = x + 1; i <= N; i += i & -i)
fen[i] += y;
}
long long sum(int x) {
long long res = 0;
for (int i = x; i > 0; i -= i & -i)
res += fen[i];
return res;
}
long long sum(int l, int r) {return sum(r) - sum(l);}
int getLeft(int x) {
int s = sum(x);
x = 0;
for (int i = 1 << 18; i > 0; i /= 2) {
if (x + i <= N && fen[x + i] < s) {
x += i;
s -= fen[x];
}
}
return x;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
Tree t1(n), t2(n);
vector<vector<int>> query(n);
vector<int> lb(m), sz(2 * n - 1, 1);
vector<long long> ans(m, -1);
int c1 = 0, c2 = 0;
for (int i = 0; i < m; ++i) {
char op;
cin >> op;
if (op == 'U') {
int a, b;
cin >> a >> b;
--a;
--b;
int p = n + (c1++);
t1.parent[t1.id[a]] = t1.parent[t1.id[b]] = p;
t1.lc[p] = t1.id[a];
t1.rc[p] = t1.id[b];
t1.id[a] = p;
sz[p] = sz[t1.lc[p]] + sz[t1.rc[p]];
} else if (op == 'M') {
int a, b;
cin >> a >> b;
--a;
--b;
int p = n + (c2++);
t2.parent[t2.id[a]] = t2.parent[t2.id[b]] = p;
t2.lc[p] = t2.id[a];
t2.rc[p] = t2.id[b];
t2.id[a] = p;
} else if (op == 'A') {
int x;
cin >> x;
--x;
t1.mod[t1.id[x]].push_back(i);
} else if (op == 'Z') {
int x;
cin >> x;
--x;
t2.mod[t2.id[x]].push_back(i);
} else {
int x;
cin >> x;
--x;
query[x].push_back(i);
}
}
function<void(int)> dfs1 = [&](int u) {
for (int i : t2.mod[u])
add(i, 1);
if (u < n) {
for (int i : query[u])
lb[i] = getLeft(i);
} else {
dfs1(t2.lc[u]);
dfs1(t2.rc[u]);
}
for (int i : t2.mod[u])
add(i, -1);
};
function<void(int)> dfs2 = [&](int u) {
for (int i : t1.mod[u])
add(i, sz[u]);
if (u < n) {
for (int i : query[u])
ans[i] = sum(lb[i], i);
} else {
dfs2(t1.lc[u]);
dfs2(t1.rc[u]);
}
for (int i : t1.mod[u])
add(i, -sz[u]);
};
for (int i = 0; i < n + c2; ++i)
if (t2.parent[i] == -1)
dfs1(i);
for (int i = 0; i < n + c1; ++i)
if (t1.parent[i] == -1)
dfs2(i);
for (int i = 0; i < m; ++i)
if (ans[i] != -1)
cout << ans[i] << "\n";
return 0;
}

CF571D Campus(19-1)的更多相关文章

  1. 【刷题-PAT】A1095 Cars on Campus (30 分)

    1095 Cars on Campus (30 分) Zhejiang University has 8 campuses and a lot of gates. From each gate we ...

  2. Linux运维必会的实战编程笔试题(19题)

    以下Linux运维笔试面试编程题,汇总整理自老男孩.马哥等培训机构,由运维派根据实战需求,略有调整: 企业面试题1:(生产实战案例):监控MySQL主从同步是否异常,如果异常,则发送短信或者邮件给管理 ...

  3. 《TCP/IP具体解释》读书笔记(19章)-TCP的交互数据流

    在TCP进行传输数据时.能够分为成块数据流和交互数据流两种.假设按字节计算.成块数据与交互数据的比例约为90%和10%,TCP须要同一时候处理这两类数据,且处理的算法不同. 书籍本章中以Rlogin应 ...

  4. 复旦高等代数I(19级)每周一题

    本学期的高等代数每周一题活动计划从第2教学周开始,到第15教学周结束,每周的周末公布一道思考题(共14道,思考题一般与下周授课内容密切相关),供大家思考和解答.每周一题将通过“高等代数官方博客”(以博 ...

  5. GO语言编译环境采用gosublime(19新版)

    环境:博主已下载好,并安装在E:/SDK,使用过sublime text3,有git 0x00 环境变量 默认已经有GOPATH(代码存放在这),PATH(安装go的bin目录即E:\SDK\bin) ...

  6. PAT A1095 Cars on Campus (30 分)——排序,时序,从头遍历会超时

    Zhejiang University has 8 campuses and a lot of gates. From each gate we can collect the in/out time ...

  7. Sicily 1031: Campus (最短路)

    这是一道典型的最短路问题,直接用Dijkstra算法便可求解,主要是需要考虑输入的点是不是在已给出的地图中,具体看代码 #include<bits/stdc++.h> #define MA ...

  8. CTSC2016&&APIO2016滚粗记&&酱油记&&游记<del>(持续更新)</del>

    挖一波坑 #include <cstdio> using namespace std; int main(){ puts("转载请注明出处:http://www.cnblogs. ...

  9. Win95+IE3 – Win10+IE11全版本执行漏洞(含POC)

    微软本月安全更新修复了一个潜藏了18年的IE远程代码执行漏洞(CVE-2014-6332),可以说是给windows吃了一颗大补丸.缺陷出现在VBScript的代码中,自Windows 95首次发布( ...

随机推荐

  1. Mac-Mysql忘记root密码

    cd /usr/local/mysql/bin 切换到root权限 ,需要输入密码: sudo su 输入之后会看见如下信息: sh-3.2# 使用如下命令以安全模式运行mysql ./mysqld_ ...

  2. qt creator源码全方面分析(2-10-4)

    目录 Plugin Life Cycle Plugin Life Cycle 为了能够编写Qt Creator插件,您必须了解启动或关闭Qt Creator时,插件管理器所采取的步骤. 本节详细描述插 ...

  3. asp.net mvc项目实战遇见问题及解决方式----ajax请求500错误,请求多表数据

    ajax请求出现500错误——但是想实现的功能是,把一个页面分成了两份,点击右边导航栏,利用ajax请求,请求数据,在右边出现相应页面,当时使用的是partialAction然后出现了这个500错误, ...

  4. 写给Unity开发者的iOS内存调试指南

    0x00 前言 工作的过程中,常常会发现有小伙伴对Unity的Profiler提供的内存数据与某些原生平台Profiler工具,例如iOS系统和Xcode,所提供的内存数据有差异而感到好奇.而且大家对 ...

  5. Android EditText不可编辑单行显示能滑动查看内容

    遇到问题 有时为了节约界面控件,可以界面的美观,我们会使用单行显示 singleLine,如果使用 Enable = false 输入框文字呈现灰色,并且也无法操作. 想要实现的效果是,单行显示,不能 ...

  6. Typora自动编号设置

    找到C:\Users\用户名\AppData\Roaming\Typora\themes\路径下的base.user.css,用文本编辑器打开(若不存在,则自己创建一个),将一下内容复制进去,然后重启 ...

  7. Nginx架构分析(20200202)

    Nginx模块化 Nginx基于模块化设计,每个模块是一个功能实现,分布式开发,团队协作 核心模块.标准HTTP模块.可选HTTP模块.邮件模块.第三方模块 编译后的源码目录objs/ngx_modu ...

  8. Jupyter Notebook 常用快捷键 (转)

    Jupyter Notebook 有两种键盘输入模式. 编辑模式,允许你往单元中键入代码或文本:这时的单元框线是绿色的. 命令模式,键盘输入运行程序命令:这时的单元框线为蓝色. 命令模式 (按键 Es ...

  9. css背景颜色、背景图片,以及列表的多种样式

    背景样式 • background-color 设置元素的背景颜色.• background-image 把图像设置为背景.• background-position 设置背景图像的起始位置.• ba ...

  10. 【spring boot】SpringBoot初学(8)– 简单整合redis

    前言 到目前为止,把项目中需要用到的:properties读取.数据源配置.整合mybatis/JdbcTemplate.AOP.WebService.redis.filter.interceptor ...