P1903 [国家集训队]数颜色 (带修改莫队)
题目描述
墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会向你发布如下指令:
1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。
2、 R P Col 把第P支画笔替换为颜色Col。
为了满足墨墨的要求,你知道你需要干什么了吗?
输入输出格式
输入格式:
第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。
第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。
第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。
输出格式:
对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。
输入输出样例
说明
对于100%的数据,N≤10000,M≤10000,修改操作不多于1000次,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。
来源:bzoj2120
//感谢xxy dalao的指导, 虽然不得不看了blog才A了这道题。。。。 //但是为什么他们一个 dfs 10+ ms就过,我却跑了100+ ?。。。。。 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std; const int N=1e4+;
const int M=1e6+; int n,m;
int a[N];
int ans;
int belong[N];
int c[M];
int query_cnt,modify_cnt;
struct Query //询问操作
{
int ans; //这次询问的答案
int l,r; //这次询问的左右区间
int tim; //这是第几次询问,便于最后将询问排序输出ans
int tim_modify; //记录这次询问是在第几次修改之后的,便于修改和撤销
}query[N];
struct Modify //修改操作
{
int tim; //这是第几次修改操作
int pos,col,pre_col; //修改的位置、修改之前的颜色、修改之后的颜色
}modify[N]; int read()
{
char c=getchar();int num=;
for(;!isdigit(c);c=getchar())
if(c=='Q')
return ;
else if(c=='R')
return ;
for(;isdigit(c);c=getchar())
num=num*+c-'';
return num;
} bool cmp1(const Query &a,const Query &b) //将询问操作排序
{
if(belong[a.l]==belong[b.l]) //为了保证效率,按照三个关键字排序,前两个和普通的不带修改的莫队一样,第三个关键字是修改时间
if(belong[a.r]==belong[b.r])
return a.tim_modify<b.tim_modify;
else
return belong[a.r]<belong[b.r];
return belong[a.l]<belong[b.l];
} bool cmp2(const Query &a,const Query &b) //将query按照询问时间排序,便于输出ans
{
return a.tim<b.tim;
} int main()
{
n=read(),m=read();
int size=sqrt(n);
for(int i=;i<=n;++i)
a[i]=read(),belong[i]=(i-)/size+;
for(int i=,type;i<=m;++i)
{
type=read();
if(type==)
{
++query_cnt;
query[query_cnt].l=read();
query[query_cnt].r=read();
query[query_cnt].tim=query_cnt; //记录这是第几次询问
query[query_cnt].tim_modify=modify_cnt; //记录当前询问是在第几次修改之后
}
else
{
++modify_cnt;
modify[modify_cnt].pos=read();
modify[modify_cnt].col=read(); //修改之后的值
modify[modify_cnt].tim=modify_cnt;
modify[modify_cnt].pre_col=a[modify[modify_cnt].pos]; //记录修改之前的值
a[modify[modify_cnt].pos]=modify[modify_cnt].col; //修改
}
}
for(int i=modify_cnt;i;--i) //把修改了的a数组还原回去
a[modify[i].pos]=modify[i].pre_col;
sort(query+,query+query_cnt+,cmp1);
int now_modify=,l=,r=;
for(int i=;i<=query_cnt;++i) //当时被卡在了修改和撤销上,没理解透彻,不知道该不该更新ans,因为当时觉得如果更新了ans的话会让后边在移动左右端点更新值得时候重复,其实不然,因为如果当前修改的值在当前询问的区间中,那么它是不会被更改的(因为改到左右端点的时候就停止了,不会来改它),如果不在当前询问的区间内,那么在移动端点的时候,被+1的ans会被还原回去(-1),但是被-1的ans是不会变的,因为它已经没了(滑稽)
{
if(query[i].tim_modify>now_modify) //当前询问在上次修改操作之后,往后修改
{
for(int j=now_modify+;j<=query[i].tim_modify;++j)
{
if(modify[j].pos>=l&&modify[j].pos<=r) //如果修改的位置在上次询问的区间内,更新
{
--c[modify[j].pre_col];
if(!c[modify[j].pre_col])
--ans;
if(!c[modify[j].col])
++ans;
++c[modify[j].col];
}
a[modify[j].pos]=modify[j].col; //修改
}
}
if(query[i].tim_modify<now_modify) //当前询问在上次修改操作之前,撤销修改
{
for(int j=now_modify;j>query[i].tim_modify;--j)
{
if(modify[j].pos>=l&&modify[j].pos<=r)
{
--c[modify[j].col]; //把修改后的数的值还原回去
if(!c[modify[j].col])
--ans;
if(!c[modify[j].pre_col]) //被修改了的数的值还原回去
++ans;
++c[modify[j].pre_col];
}
a[modify[j].pos]=modify[j].pre_col; //撤销
}
}
if(l<query[i].l)
{
for(int j=l;j<query[i].l;++j)
{
--c[a[j]];
if(!c[a[j]])
--ans;
}
}
if(l>query[i].l)
{
for(int j=query[i].l;j<l;++j)
{
if(!c[a[j]])
++ans;
++c[a[j]];
}
}
if(r<query[i].r)
{
for(int j=r+;j<=query[i].r;++j)
{
if(!c[a[j]])
++ans;
++c[a[j]];
}
}
if(r>query[i].r)
{
for(int j=query[i].r+;j<=r;++j)
{
--c[a[j]];
if(!c[a[j]])
--ans;
}
}
l=query[i].l,r=query[i].r; //更新查询区间
query[i].ans=ans; //记录这次查询的答案
now_modify=query[i].tim_modify; //更新最新一次修改时间
}
sort(query+,query+query_cnt+,cmp2);
for(int i=;i<=query_cnt;++i)
{
printf("%d\n",query[i].ans);
}
return ;
}
P1903 [国家集训队]数颜色 (带修改莫队)的更多相关文章
- BZOJ2120/洛谷P1903 [国家集训队] 数颜色 [带修改莫队]
BZOJ传送门:洛谷传送门 数颜色 题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R ...
- P1903 [国家集训队]数颜色 带修改莫队板子
大概就是要多加一维time 然后按照(l的块,r的块,time)为关键字排序 转移区间修改还是按照莫队的方式(每个修改要记修改前后的状态) 然后玄学dalao告诉窝块大小设为\(O(n^{\frac{ ...
- bzoj 2120 数颜色 带修改莫队
带修改莫队,每次查询前调整修改 #include<cstdio> #include<iostream> #include<cstring> #include< ...
- BZOJ2120数颜色(带修改莫队)
莫队算法是一种数据结构的根号复杂度替代品,主要应用在询问[l,r]到询问[l+1,r]和[l,r+1]这两个插入和删除操作复杂度都较低的情况下.具体思想是:如果把一个询问[l,r]看做平面上的点(l, ...
- [国家集训队][bzoj2120] 数颜色 [带修改莫队]
题面: 传送门 思路: 这道题和SDOI2009的HH的项链很像,只是多了一个修改 模板套上去呀 莫队学习请戳这里:莫队 Code: #include<iostream> #include ...
- COGS.1901.[模板][国家集训队2011]数颜色(带修改莫队)
题目链接 COGS BZOJ2120 洛谷P1903 /* Add和Subd函数中的vis不能直接设为=1或=0 比如 l=1,r=0 -> l=3,r=5 时,[1,5]的vis标记全都是1 ...
- bzoj2120 / P1903 [国家集训队]数颜色 / 维护队列(带修改莫队)
P1903 [国家集训队]数颜色 / 维护队列 带修改的莫队 在原有指针$(l,r)$上又添加了时间指针$t$ 贴一段dalao的解释 带修改的莫队,和原版莫队相比,多了一个时间轴 原版莫队是将区间( ...
- 洛谷 P1903 [国家集训队]数颜色 解题报告
P1903 [国家集训队]数颜色 题目描述 墨墨购买了一套\(N\)支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1.Q L R代表询问你从第\(L\) ...
- P1903 [国家集训队]数颜色 / 维护队列 带修改莫队
题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2 ...
随机推荐
- [LOJ2537] [PKUWC2018] Minimax
题目链接 LOJ:https://loj.ac/problem/2537 洛谷:https://www.luogu.org/problemnew/show/P5298 Solution 不定期诈尸 好 ...
- 基于工作组消息队列高可用&msmq-wcf故障
场景: msmq 1# server故障手工切换到2# server,msmq-wcf service宿主服务重启后,无法成功读取消息,状似service不工作.无法监听到数据传输. 解决过程: 反复 ...
- 在Unity中创建VR游戏
添加VR插件为了为您选择的平台创建VR游戏,我们需要下载几个插件.出于本教程的目的,我将向您展示如何上传到Android平台.要上传到iOS,您需要下载 Xcode. 现在让我们下载Unity的Goo ...
- mysql 存储过程、视图---创建、调用、删除
之前一直用的是Sql Server数据库,最近偶然机会接触到mysql.这里总结了关于mysql 存储过程.视图的“创建.调用.删除”示例 ============================== ...
- 【亲测有效】安装npm慢的解决方案
使用淘宝的NPM库:npm install -gd express --registry=http://registry.npm.taobao.org
- Spring @Transactional注解不起作用解决办法及原理分析
Transactional失效场景介绍 第一种 Transactional注解标注方法修饰符为非public时,@Transactional注解将会不起作用.例如以下代码. 定义一个错误的@Trans ...
- flask-sqlalchemy用法详解
一. 安装 $ pip install flask-sqlalchemy 二. 配置 配置选项列表 : 选项 说明 SQLALCHEMY_DATABASE_URI 用于连接的数据库 URI .例如:s ...
- java安全相关知识
基本概念 JVM:java虚拟机,Java编译程序将生成Java虚拟机上可运行的目标代码,使得Java程序可以再不同平台不加修改的运行.JVM包含完善的硬件架构,主要分为五大模块-类装载器子系统.运行 ...
- Redis一主二从Sentinel监控配置
本文基于Redis单实例安装安装.https://gper.club/articles/7e7e7f7ff7g5egc4g6b 开启哨兵模式,至少需要3个Sentinel实例(奇数个,否则无法选举Le ...
- 使用virtualbox安装unbuntu开启共享文件夹时遇到的权限问题
在安装完虚拟机之后,开启文件夹共享,发现只能用root进行访问,个人帐号无权限: cust@hqjia-desktop:/media$ ll drwxr-xr-x 4 root root 4096 2 ...