zoukankan      html  css  js  c++  java
  • NOI2019 I 君的商店

    I 君的商店

    不知道这道题是怎么被人想出来的,tql

    题意:

    有一张图,(n) 个点,(m) 条边,但是你不知道这张图具体的模样,你可以执行 4 种操作来确定这张图:

    • 每个点初始有一个状态 (0)
    1. ( m modify(x)),修改点 (x) 的状态以及其所有与其有边的点的状态。
    2. ( m query(x)),查询点 (x) 的状态。
    3. ( m report(x,y)),告诉交互库存在一条 (x o y) 的无向边,并储存之。
    4. ( m check(x)),检查 (x) 的所有出边是否均被储存。

    其中 (1,2,4) 操作均有次数限制,令 (L_m,L_q,L_c) 依次表示其操作次数限制。

    部分分:

    1. 暴力即可。
    2. (Nle 2cdot 10^5,M=N/2,L_m,L_qle 18N,L_c=0)
    3. (Nle 2cdot 10^5,M=N-1,L_m,L_qle 18N),保证为链。
    4. (3),保证为树。
    5. 保证为内向树。
    6. 一张图,(Nle 2cdot 10^5,Mle 3cdot 10^5,L_q,L_mle 50N)
    • (2) 类数据

    考虑按照二进制位进行拆位处理,如果当前位是 (1) 那么修改它,然后依次查询。

    如果这个点连的点在当前位不同,那么其状态一定改变。

    否则一定不变,那么可以直接算出来这个点的对应点。

    • (3) 类数据

    发现做法 (2) 实际上可以得到这个点连出去的点的编号的异或和。

    (0) 号的出边,这个可以 (mathcal O(n)) 确定,接下来可以直接递推两边的结果。

    • (4) 类数据

    考虑如何在树上确定,类似 (2) 的处理,接下来我们仍然先处理 (0) 的出边是谁,考虑如果知道了叶子节点是谁,那么根据我们得到的信息可以轻易的还原树。

    所以每次修改 (x),然后查询 (f_x) 是否改变即可得到所有的叶子节点。

    大概是一个剥叶子的思路。

    • (5) 类数据

    注意到父亲是单调的,考虑二分一个 (x),然后将 ([0,x)) 均进行修改,那么如果 (uin [x,n)) 的状态改变了,则其与这个区间存在连边。

    对于所有点都需要求,显然可以换成整体二分。

    • (6) 类数据

    我们先随机一个排列,如果这个点往在它前面的点连边数为奇数,那么设这个点为关键点。

    可以证明,关键点的数量期望为 (frac{n}{3})

    我们考虑一个算法,使得每轮可以至少找出关键点向前连边的一条边。

    考虑二分一个 (x),然后依次操作 (a_{0sim x-1}),接着查询所有点,显然处于后面的点如果状态改变,说明其往前面的集合至少有一条边。

    然后将二分换成类似于整体二分的处理,注意到如果一个集合与你的连边为偶数,那么在处理这个集合的时候我们将所有点都进行 modify 对你依然没有影响,不过当然也可以暴力点修改后再改回来,于是显然这样可以筛出 (frac{n}{3}) 条边,这玩意儿的查询/修改次数显然为 (T(n)=mathcal O(nlog n) +T(frac{2n}{3})=mathcal O(3nlog n))

    当然,我们显然在单次操作时要去除已操作的边的影响,这样才可以保证单次至少可以筛出 (frac{n}{3}) 条其他边。

    通过 check 操作进行适当剪枝可以在 (mathcal O(50N)) 的查询通过本题。

  • 相关阅读:
    SharePoint与RMS集成中关于权限的一个技术点
    SharePoint Alert
    SharePoint Explorer View
    在查看network traffic的时候, TCP Chimney offload的影响
    SharePoint Profile Import
    为SharePoint添加Event Receiver
    通过Telnet来发送邮件
    如何查看扩展出来的web application?
    Windows Host 文件
    Wscript.Shell 对象详细介绍
  • 原文地址:https://www.cnblogs.com/Soulist/p/13653778.html
Copyright © 2011-2022 走看看