题目链接:https://www.luogu.org/problemnew/show/P1903

题目大意:中文题目

具体思路:莫队单点修改+区间询问模板题,在原来的区间询问的基础上,我们要记录当前这次操作之前单点修改的操作都有哪些,如果有多余的操作,就先消除这些操作:如果操作数还不够,就在加上这些操作就可以了,这个题会卡常数,注意block的赋值。

block的赋值 = ceil(exp((log(n)+log(num1))/3));这里的num1指的是操作数,n代表点的个数。

然后我们可以对比一下我写的这篇文章,

P1494 [国家集训队]小Z的袜子(莫队)

,在每一次指针的移动的时候,这个题需要把先前的影响给去掉,又因为每一次值的个数需要平方,所以需要先把原来的影响给去掉再去加上新的影响。而这个题我们是只需要判断当前的点是1还是0就可以了。

 

AC代码:

 #include<iostream>
#include<cmath>
#include<stdio.h>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
# define ll long long
const int maxn = 2e6+;
int a[maxn],block;
struct node1
{
int l,r,pos,id,num;
bool friend operator < (node1 t1,node1 t2)
{
if(t1.l/block!=t2.l/block)return t1.l/block<t2.l/block;
if(t1.r/block!=t2.r/block)return t1.r/block<t2.r/block;
return t1.num<t2.num;
}
} q1[maxn];
struct node2
{
int pos,val;
} q2[maxn];
int tot,vis[maxn],ans[maxn];
void update(int id,int pos)
{
if(q2[pos].pos>=q1[id].l&&q2[pos].pos<=q1[id].r)
{
if(--vis[a[q2[pos].pos]]==)
tot--;
if(++vis[q2[pos].val]==)
tot++;
}
swap(a[q2[pos].pos],q2[pos].val);
}
inline int read()
{
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'',c=getchar();}
return x*f;
}
void solve(int num1)
{
int num=,l=,r=;
tot=;
for(int i=; i<=num1; i++)
{
while(l<q1[i].l)if(--vis[a[l++]]==)tot--;
while(l>q1[i].l)if(++vis[a[--l]]==)tot++;
while(r<q1[i].r)if(++vis[a[++r]]==)tot++;
while(r>q1[i].r)if(--vis[a[r--]]==)tot--;
while(num<q1[i].num){
num++;
update(i,num);
}
while(num>q1[i].num)
{
update(i,num);
num--;
}
ans[q1[i].id]=tot;
}
return ;
}
int main()
{
// cout<<pow(50000,5.0/3.0)<<endl;
// memset(vis,0,sizeof(vis));
// freopen("hqx.in","r",stdin);
int n,m;
n=read();
m=read();
//scanf("%d %d",&n,&m);
for(int i=; i<=n; i++)
{
a[i]=read();
}
char str[];
int st,ed;
int num1=,num2=;
while(m--)
{
scanf("%s",str);
st=read();
ed=read();
if(str[]=='Q')
{
q1[++num1].l=st;
q1[num1].r=ed;
q1[num1].num=num2;
q1[num1].id=num1;
}
else if(str[]=='R')
{
q2[++num2].pos=st;
q2[num2].val=ed;
}
}
block=ceil(exp((log(n)+log(num1))/));
sort(q1+,q1+num1+);
solve(num1);
for(int i=; i<=num1; i++)
{
printf("%d\n",ans[i]);
}
// for(int i=1;i<=5;i++){
// cout<<i<<" "<<vis[i]<<endl;
// }
return ;
}

 

最新文章

  1. Ubuntu实现树莓派交叉编译
  2. C#开源项目汇总
  3. 蓝灯github地址
  4. Android中表示尺寸的六种度量单位
  5. iOS应用的真机调试
  6. php将SQL查询结果赋值给变量
  7. 一款新型的智能家居WiFi选择方案——SimpleWiFi在无线智能家居中的应用
  8. poj1185(状压dp)
  9. Cesium 海拔 经纬度 展示
  10. shiro(四)项目开发中的配置、
  11. centos 下Python独立虚拟环境创建
  12. openwrt修改hosts
  13. 【转载】Oracle 中count(1) 、count(*) 和count(列名) 函数的区别
  14. Lodop打印语句最基本结构介绍(什么是一个任务)
  15. Ubuntu 实践
  16. 解决在antd中使用 autoprefixer 9.4.5 会抛出错误 Replace text-decoration-skip: ink to text-decoration-skip-ink: auto, because spec had been changed 的问题
  17. 6. 纯 CSS 绘制一颗闪闪发光的璀璨钻石
  18. docker 安装vim
  19. 浅谈欧几里得算法求最大公约数(GCD)的原理及简单应用
  20. ios逆向工程-静态分析

热门文章

  1. hdu 2476&quot;String painter&quot;(区间DP)
  2. Luogu P4015 运输问题
  3. (贪心和优先队列) POJ1862 Stripies
  4. Win7下mysql的安装
  5. TF的使用
  6. Hadoop HDFS常用操作命令
  7. 3、JPA-API
  8. python css盒子型 浮动
  9. JWT认证
  10. VirtualBox安装Ubuntu14.04