A93034.「SNOI2022」垃圾回收

普及+/提高

官方

通过率:0%

时间限制:2.00s

内存限制:512MB

题目描述

通常的情况下,编程语言在管理内存时进行如下的选择:

  • 让用户进行手动内存管理(C, C++, Rust 等),这会收获很好的性能,但是给用户提供了很大的编程负担。
  • 使用垃圾回收系统(Java,Go 等),这需要维护一个运行时系统,并且在内存使用和程序性能方面造成了许多不可预测的负担。

尽管存在许多的问题,目前最通用的自动化内存管理手段始终为 Tracing Garbage Collector。这种做法的最基础的思路是维护对象间的引用关系,形成一张图,每次回收时通过扫描引用关系推导出已经无法被访问到的对象,释放它们占用的内存。而这种传统的做法最大的问题在于维护引用链需要造成很大的开销,并且随着维护的对象越多,扫描的代价也会越大。

小 L 是一个喜欢思考的女孩子,她发现维护 Garbage Collector 是一件非常复杂的事情,于是她决定考虑一个更简单的模型(注意它与任何现实中的 GC 规则可能是完全不同的!)。

对于一个 nn 个点 mm 条边的无向图,没有重边自环,点和边均从 11 开始标号。其中每个节点代表一个占用了一定内存的对象,每条边对应一个引用关系(注意这里的引用关系是无向的),程序从第 00 秒开始运行,在第 q+1q + 1 秒结束运行。对于 i=1,2,3,,qi = 1, 2, 3, \dots, q 的每个时刻 ii 发生以下两种操作之一:

  • DELETE ii,删除边 (xi,yi)(x_i,y_i),保证不会删除已经被删除的边。
  • GC,进行一次内存回收,即杀死所有从起点出发不能访问到的点,释放它们占用的内存。(注意这里对节点的删除不会删除与这些点相连的边)

你可以认为这些操作是被瞬间执行完成的,在所有操作执行后,也就是第 q+1q + 1 秒,程序结束,删除所有剩余的节点(包括 11 号点)。

ii 个点占用的内存为 aia_i,现在请你求出 i=1naiti\sum_{i = 1}^{n} a_i \cdot t_i,这里 tit_i 表示第 ii 个点存活的时间,在第 00 秒,所有节点都是存活的。

输入格式

输入的第一行是三个正整数 n,m,qn, m, q,分别表示对象的个数,引用关系的个数,操作的个数。

接下来的 mm 行每行 22 个正整数 xi,yix_i, y_i 表示第 ii 条引用关系的两个端点。

接下来的 qq 行每行为以下两种形式之一,第 ii 行表示在第 ii 秒发生的操作:

  • 字符串 DELETE 和正整数 xx,含义见「题目描述」
  • 字符串 GC,含义见「题目描述」

接下来的一行有 nn 个正整数 a1,a2,,ana_1,a_2,\dots,a_n,表示每个对象占用的内存大小。

输出格式

输出一行一个整数表示程序的开销,含义见「题目描述」。

输入输出样例

  • 输入#1

    6 6 8
    1 2
    2 3
    2 4
    1 4
    2 5
    1 6
    GC
    DELETE 5
    DELETE 3
    GC
    DELETE 1
    GC
    DELETE 2
    GC
    1 2 3 4 5 6
    

    输出#1

    149
    

说明/提示

对于全部数据,1n,m,q4×105,1ai1081\le n,m,q\le 4\times 10^5,1\le a_i\le 10^8

具体的数据规模与约定见下表。

测试点编号 nn mm qq 特殊约定
121\sim 2 500\le 500 $\le 500 $ 500\le 500
353\sim 5 3000\le 3000 $\le 3000 $ 3000\le 3000
6106\sim 10 5000\le 5000 $\le 5000 $ 5000\le 5000
111411\sim 14 2×105\le 2\times 10^5 n1n-1 2×105\le 2\times 10^5 保证一开始图是一棵树
151615\sim 16 $\le 2\times 10^5 $ 2×105\le 2\times 10^5 $\le 2\times 10^5 $
172017\sim 20 4×105\le 4\times 10^5 $\le 4\times 10^5 $ 4×105\le 4\times 10^5
首页