题意

\(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. Software Testing Concepts

    Software Testing Concepts

  2. finished with exit code -1073740791 (0xC0000409)解决方案

    1.在用keras框架跑NER的train时,而且只是在用了keras_contrib.layers的CRF时出现问题: 遇到无错跳出finished with exit code -10737407 ...

  3. php 截取字符串长度 并 把超出规定长度的内容用...替代

    <?php header("content-type:text/html;charset=utf-8");#设置文件编码 error_reporting(E_ALL);#设置 ...

  4. helm 错误the server has asked for the client to provide credentials

    一.造成错误的原因 不小心把helm的RBAC权限文件删除了.虽然重新apply了RBAC配置,但是已经无法使用helm install了. 二.解决方法 把运行的tiller的pod干掉,让他自动重 ...

  5. 珠峰-buffer-流事件

    #### Buffer // 字符串的二进制转10进制 let r = parseInt('11111111', 2); console.log(r); // 打印 255 // Number类型转为 ...

  6. 嗅探、DNS劫持配合CS钓鱼

    本章节讲述的是嗅探和DNS劫持的利用 嗅探:同一个局域网下,原本应该丢弃的包,被保留下来,即使不开双向欺骗 Driftnet工具:Driftnet监视网络流量,抓取网络流量中的JPEG和GIF图像.这 ...

  7. 加速github访问速度

    打开https://www.ipaddress.com/ 查询以下三个链接的DNS解析地址 github.com assets-cdn.github.com github.global.ssl.fas ...

  8. C# 通过反射检查属性是否包含特定字符串

    public static bool StringFilter(this object model,string filterStr) { if (string.IsNullOrEmpty(filte ...

  9. win下python脚本以unix风格换行保存将会报错为编码问题 SyntaxError: encoding problem:gbk

    utf-8与gbk编码都报错 从别人的github拉下来一个python脚本. 直接运行,python报错如下: File ".\drag_files_do_event.py", ...

  10. Html介绍,认识html文件基本结构

    一个HTML文件的基本机构如下: <html><head>...</head><body>...</body></html>代码 ...