题目链接

我们给每个连通块图上一种颜色。不同的连通块涂不同的颜色。

首先,我们定义\(f_r\)表示:使\([l,r]\)包括\([1,r]\)里所有颜色的最大的\(l\)。

然后我维护一个变量\(pos\),表示从\(pos\)到\(n\)的这些点\(i\)(\(\forall i\in[pos,n]\)),\([1,i]\)中包含了当前所有的颜色。容易发现这个条件就等价于\([1,pos]\)中包含了所有颜色。对每次操作显然\(pos\)是单调减的,所以就很好维护。在并查集时,令每个连通块的根,也就是fa[x]==x的那个节点,是这个连通块里的最小位置。即在合并时:fa[max(x,y)]=min(x,y)。这样我们就可以这么维护\(pos\):

//初始化:
pos=n;
//每次询问时:
while(pos>1&&get_father(pos)!=pos)pos--;

有了\(pos\)之后,一次询问的答案就是对\([pos,n]\)这段的每个\(i\),求\(i-f_i+1\)的最小值。这就是\(f_i\)的作用。

我们定于\(\text{next}_i\)表示\(i\)后面第一个和\(i\)同色的位置。则容易发现\(\displaystyle f_i=\min_{\text{next}_j>i}\{j\}\)。其含义是:对于每一种颜色,你取它在\(i\)前面最后一次出现的位置,然后对这些位置取\(\min\),得到的就是使得\([l,i]\)包含所有\(i\)前面的颜色的最大的\(l\)了。如果已知了\(\text{next}\)数组,我们用线段树维护\(\text{next}\)的区间最大值,则某个点\(i\)的\(f_i\)可以通过线段树上二分,在\(O(\log n)\)的时间内求出。

线段树上二分程序片段:

int query(int p,int l,int r,int pos){
    if(l==r){
        assert(mx[p]>pos);
        return l;
    }
    int mid=(l+r)>>1;
    if(mx[p<<1]>pos)return query(p<<1,l,mid,pos);
    else return query(p<<1|1,mid+1,r,pos);
}

回到问题,首先我们肯定要启发式合并,这样我们就有机会暴力更改集合里的每个点,便于我们维护\(f\)。

对于一个点\(u\),如果:

  • \(u\)的颜色变了;

  • 或\(u\)左边新插入了一个颜色和\(u\)不一样的点;

  • 或\(u\)右边新插入了一个颜色和\(u\)不一样的点;

那么原本一些位置的\(f\)值就会变化。具体哪些位置会变呢,我们发现只有\(f_i=u\)的这些\(i\)会变。又因为\(f\)是单调递增的,所以\(f_i=u\)的\(i\)一定在一段连续的区间。

证明:只有原本\(f_i=u\)的这些\(i\)的\(f\)值会变。

考虑\(f_i<u\)时,这样的\(f_i\)瓶颈不在\(u\),也就是说它在取\(\min\)时会取到一个比\(u\)还小的位置。所以这样的\(f_i\)显然不会变。

\(f_i>u\)时,说明\(u\)后面还有一个和\(u\)同色的点在\(i\)之前,所以\(u\)就和\(i\)无关了。

现在我们考虑求出\(f_i=u\)的\(i\)的区间。我们用另一棵线段树,维护\(f\)的区间最大值、区间最小值。这样就可以线段树上二分出这个区间。

考虑这段区间\([l,r]\),它在我们进行操作前\(f\)值是相等的,操作后它会分裂成若干段区间。我也不知道具体会分裂成几段。

但是!

最多只有\(2\)段会和前后的合并起来。(这里的合并是指变成\(f\)值相同的连续段,这只是我们证明复杂度用的,在代码里并不需要真的合并)。而整个序列最多只有\(n\)段\(f\)值,每次最多只会减小\(2\)段,因此增加的段数总量不超过\(n+2m\),是\(O(n)\)级别的!

这样我们就可以一段一段暴力跳了。

最后的问题是对于一个\(l\),如何跳到最靠后的一个和它\(f\)值相等的\(r\)(这里指修改后的\(f\)值)。

首先根据最开始的讨论,我们可以求出\(l\)在修改后的\(f\)值,我们记为\(pre\)。则\(l\)之后的第一个和\(l\)的\(f\)值不同的地方在\(\text{next}_{pre}\)。

证明:

对于每个\(i\in[l,\text{next}_{pre})\),\(f_i\)首先不可能小于\(f_l\),因为这样不符合\(\displaystyle pre=\min_{\text{next}_j>l}\{j\}\)的性质。

然后\(f_i\)也不可能\(>pre\),因为\(i<\text{next}_{pre}\),所以取\(\min\)时就一定会取到\(pre\)。

因此\(\forall i\in[l,\text{next}_{pre}),f_i=pre\)。

又因为\(i\geq \text{next}_{pre}\)时取\(\min\)一定不会取到\(pre\)了,所以\(f_i>pre\)。

综上,\(l\)之后的第一个和\(l\)的\(f\)值不同的地方在\(\text{next}_{pre}\)。

于是我们的操作就是:

  • 对每个被更新的\(u\),找出对应的\([l,r]\);

  • 求出\(pre=f_l\),对\([l,\min(\text{next}_{pre}-1,r)]\)区间的\(f\)值进行区间覆盖(全部改成\(f_l\));

  • 令\(l=\text{next}_{pre}\),重复第二步,直到\(l>r\)时结束。

具体实现时我们把所有要处理的\(u\)压到一个vector里即可。

因为是启发式合并的基础上用线段树修改,所以复杂度\(O(n\log^2 n)\)。

参考代码

题解 zr1212 【20WC集训】货币的更多相关文章

  1. 2018.7.16 题解 2018暑假集训之Roads-roads

    题面描述 有标号为1--n的城市与单行道相连.对于每条道路有两个与之相关的参数:道路的长度以及需要支付的费用(用硬币的数量表示) 鲍勃和爱丽丝曾经生活在城市1.在注意到爱丽丝在他们喜欢玩的卡牌游戏中作 ...

  2. AtCoder Grand Contest 017 题解

    A - Biscuits 题目: 给出 \(n\) 个物品,每个物品有一个权值. 问有多少种选取方式使得物品权值之和 \(\bmod\space 2\) 为 \(p\). \(n \leq 50\) ...

  3. [NOIP提高组2018]货币系统

    [TOC] 题目名称:货币系统 来源:2018年NOIP提高组 链接 博客链接 CSDN 洛谷博客 洛谷题解 题目链接 LibreOJ(2951) 洛谷(P5020) 大视野在线评测(1425) 题目 ...

  4. hdu 1217(Floyed)

    Arbitrage Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  5. 【BZOJ4928】第二题 树hash+倍增

    [BZOJ4928]第二题 Description 对于一棵有根树,定义一个点u的k-子树为u的子树中距离u不超过k的部分. 注意,假如u的子树中不存在距离u为k的点,则u的k-子树是不存在的. 定义 ...

  6. 【BZOJ4930】棋盘 拆边费用流

    [BZOJ4930]棋盘 Description 给定一个n×n的棋盘,棋盘上每个位置要么为空要么为障碍.定义棋盘上两个位置(x,y),(u,v)能互相攻击当前仅 当满足以下两个条件: 1:x=u或y ...

  7. OI总结

    当下考的钟声叮当响起,该走了,一年半的OI竞赛就此结束 留下了很多遗憾.也拥有过一段美好的竞赛生活 结识了一群优秀的OI战友,一起进步一起开心一起忧愁,但这一切的一切都将在今晚变成过去式,CSp的好与 ...

  8. 【题解】P4247 [清华集训]序列操作(线段树修改DP)

    [题解]P4247 [清华集训]序列操作(线段树修改DP) 一道神仙数据结构(DP)题. 题目大意 给定你一个序列,会区间加和区间变相反数,要你支持查询一段区间内任意选择\(c\)个数乘起来的和.对1 ...

  9. 【某集训题解】【DAY 2 T3】与非

    题目描述 作为一名新世纪共产主义的接班人,你认识到了资本主义的软弱性与妥协性,决定全面根除资本主义,跑步迈入共产主义.但是当你即将跨入共产主义大门的时候,遇到了万恶的资本家留下的与非电路封印,经过千辛 ...

随机推荐

  1. shell脚本部署apache并能通过浏览器访问!

    第一步:导入httpd-2.2.17.tar包 第二步:创建一个test.sh文件(可在/root下) 第三步编写shell脚本 > 会重写文件,如果文件里面有内容会覆盖 >>这个是 ...

  2. 最全BT磁力搜索引擎,国外最受欢迎的BT-磁力网站(整理分享,每日不断更新...)

    最全BT磁力搜索引擎索引(整理分享,每日更新) 1.海盗湾 The Pirate Bay 2.磁力天堂(BT磁力搜索下载-磁力天堂) www.btaa.xyz  (资源多,下载速度可以,建议用手机访问 ...

  3. 前端学习 之 CSS(一)

    一:什么是 CSS? ·CSS 指层叠样式表 (Cascading Style Sheets) ·样式定义如何显示 HTML 元素 ·样式通常存储在样式表中 ·把样式添加到 HTML 4.0 中,是为 ...

  4. ubuntu-18.04 修改用户名密码

    1. 开放root登录 设置root密码 $ sudo passwd root 切换到root 用户 $ sudo -i 修改/etc/pam.d/gdm-autologin $ vim /etc/p ...

  5. CSP2019 滚粗记

    目录 CSP 2019 游记 DAY 0 DAY 1 DAY 2 CSP总结 自测之后 CSP 2019 游记 坐标:GD,GZ 人物:hyf 组别:J和S 任务:划水 目标:划水 任务奖励:退役证书 ...

  6. 01初步启动Hadoop服务

    1.rz命令将hadoop压缩包上传至Linux服务器中 2.tar -zxvf hadoop-2.7.7.tar.gz(解压即可用) 3.将解压出来的hadoop移到想要放的位置 mv hadoop ...

  7. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 显示代码:电脑程序输出: Sample output

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. Netsparker破解版5.3 Netsparker Enterprise 5.3.0.24388[cracked]

    Netsparker破解版5.3 Netsparker Enterprise 5.3.0.24388[cracked]该版本更新时间为2019年7月8日下载地址:1 https://www.dr-fa ...

  9. Aho-Corasick (AC) 自动机

    基础:AC自动机是建立在 trie 树和 kmp 基础之上的,为什么这么说,因为AC自动机是基于字典树的数据结构之上的,其次它是一个自动机,用到了 kmp 的失配数组的思想. 应用:在模式匹配的问题中 ...

  10. 「CH6101」最优贸易

    「CH6101」最优贸易 传送门 考虑一种贪心的思想:我们要尽量买价格小的货物,并尽量高价转卖. 我们记 : \(mn[i]\) 为从点 \(1\) 走到点 \(i\) 经过的价格最小的货物的价格. ...