正题

题目链接:http://noi.ac/problem/2007


题目大意

\(n\)个格子排成一排,每个格子有一个\(0/1\)和一个颜色。开始每个格子都是\(0\),\(q\)次操作取反一个颜色的所有格子的\(0/1\),然后询问\(1\)的格子构成的连通块数量。

\(1\leq n,q\leq 10^5\)


解题思路

可以理解为总共的\(1\)格子数减去相邻的\(1\)格子对数。

转换一下模型,每队相邻的颜色\(x,y\)之间连接一条边。

现在问题变为了每次删除或者加入一个点,求连通子图的边的数量。

那么每次加入一个点\(x\)的时间复杂度是\(O(deg_x)\),这其实是有大量重复的,因为有一些点没有被加入但是也需要判断。

考虑平衡一下复杂度,发现对于一条边连接\(x,y\),我们可以选择一个点在这个点修改的时候进行处理,若两个点的度数都在\(\sqrt m\)以内那么随便那个点处理这条边的情况就好了。若其中有一个点的度数大于\(\sqrt m\)的话,那么度数小的那个点处理。

然后两个点的度数都大于\(\sqrt m\)的话怎么办?不难发现这些点的数量不会超过\(\sqrt m\),我们将重边压缩然后随便那个点处理都可以。

这样均摊下来时间复杂度\(O(q\sqrt n)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
const int N=1e5+10;
int l,m,n,Q,w[N],c[N],deg[N],ans;
bool v[N],z[N];vector<int>e[N];
int main()
{
scanf("%d%d%d",&l,&n,&Q);
for(int i=1;i<=l;i++){
scanf("%d",&c[i]);
w[c[i]]+=1-(c[i]==c[i-1]);
if(c[i]!=c[i-1])deg[c[i]]++,deg[c[i-1]]++,m+=2;
}
int T=sqrt(m);
for(int i=1;i<=n;i++)z[i]=(deg[i]>T);
for(int i=2;i<=l;i++){
if(c[i]!=c[i-1]){
int x=c[i],y=c[i-1];
if(!z[x])e[x].push_back(y);
else e[y].push_back(x);
}
}
while(Q--){
int x;scanf("%d",&x);
int f=v[x]?-1:1;v[x]^=1;ans+=w[x]*f;
for(int i=0;i<e[x].size();i++){
int y=e[x][i];w[y]-=f;
if(v[y])ans-=f;
}
printf("%d\n",ans);
}
return 0;
}

NOI.AC#2007-light【根号分治】的更多相关文章

  1. NOI.AC#2266-Bacteria【根号分治,倍增】

    正题 题目链接:http://noi.ac/problem/2266 题目大意 给出\(n\)个点的一棵树,有一些边上有中转站(边长度为\(2\),中间有一个中转站),否则就是边长为\(1\). \( ...

  2. 7.6 NOI模拟赛 灯 根号分治

    比较容易想的题目~ 容易发现 点亮一种颜色的贡献=新增灯的数量-已经存在的边的条数. 用线段树维护并不容易.暴力的话复杂度是\(Q\cdot n\)的. 考虑根号分治 只单纯考虑度数<B的点的话 ...

  3. [CF587F]Duff is Mad[AC自动机+根号分治+分块]

    题意 给你 \(n\) 个串 \(s_{1\cdots n}\) ,每次询问给出 \(l,r,k\) ,问在 \(s_{l\cdots r}\) 中出现了多少次 \(s_k\) . \(n,q,\su ...

  4. NOI.AC 32 Sort——分治

    题目:http://noi.ac/problem/32 从全是0和1的情况入手,可以像线段树一样分治下去,回到本层的时候就是左半部的右边是1,右半部的左边是0,把这两部分换一下就行.代价和时间一样是n ...

  5. CF587F-Duff is Mad【AC自动机,根号分治】

    正题 题目链接:https://www.luogu.com.cn/problem/CF587F 题目大意 给出\(n\)个字符串\(s\).\(q\)次询问给出\(l,r,k\)要求输出\(s_{l. ...

  6. 洛谷 P6189 - [NOI Online #1 入门组]跑步(根号分治+背包)

    题面传送门 题意: 求有多少个数列 \(x\) 满足: \(\sum x_i=n\) \(x_i\geq x_{i+1}\) 答案对 \(p\) 取模. ...你确定这叫"入门"组 ...

  7. P6189 [NOI Online #1 入门组] 跑步 (DP/根号分治)

    (才了解到根号分治这样的妙方法......) 将每个数当成一种物品,最终要凑成n,这就是一个完全背包问题,复杂度O(n2),可以得80分(在考场上貌似足够了......) 1 #include < ...

  8. NOI.AC WC模拟赛

    4C(容斥) http://noi.ac/contest/56/problem/25 同时交换一行或一列对答案显然没有影响,于是将行列均从大到小排序,每次处理限制相同的一段行列(呈一个L形). 问题变 ...

  9. UOJ#33-[UR #2]树上GCD【长链剖分,根号分治】

    正题 题目链接:https://uoj.ac/problem/33 题目大意 给出\(n\)个点的一棵树 定义\(f(x,y)=gcd(\ dis(x,lca),dis(y,lca)\ )\). 对于 ...

随机推荐

  1. 阿里云rds分区

    SELECT PARTITION_NAME,TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 'xw_user_appl ...

  2. element ui loading加载开启与关闭

    参考:https://blog.csdn.net/qq_41877107/article/details/87690555 Vue项目引入element-ui,之后,将以下代码写入 mounted() ...

  3. uwp 的work project 的 取消闹钟

    private void initalAlarmHanle() { string cancelAlarm = "CancelAlarmEvent"; ConnectionManag ...

  4. Html 之自动高度 auto 和 100%高度

    HTML 高度 下面示例 设置为 Auto 和 100% <!DOCTYPE html> <html lang="en"> <head> < ...

  5. SpringBoot中的thymeleaf引擎报错

    关于:thymeleaf报错: An error happened during template parsing (template: "class path resource [temp ...

  6. Gradient checking

    所需文件:本地下载 Gradient Checking Welcome to the final assignment for this week! In this assignment you wi ...

  7. 配置双jdk

    1 CLASSPATH:.%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar 2 JAVA_HOME:%JAVA_HOME ...

  8. Ubuntu16.04 Linux 下无痛安装、配置Gogs

    本文在Win7+VMware的ubuntu 16.04中测试,安装Gogs,Install from binary. 准备工作: sudo apt-get install git sudo addus ...

  9. 浅谈可持久化Trie与线段树的原理以及实现(带图)

    浅谈可持久化Trie与线段树的原理以及实现 引言 当我们需要保存一个数据结构不同时间的每个版本,最朴素的方法就是每个时间都创建一个独立的数据结构,单独储存. 但是这种方法不仅每次复制新的数据结构需要时 ...

  10. vue 用driver 添加用户引导

    npm 安装: npm install driver.js //用户引导 import Driver from 'driver.js' import 'driver.js/dist/driver.mi ...