$n \leq 10000$的数列,$m \leq 10000$个操作,一:单点修改;二:查区间不同数字个数。修改数$\leq 1000$,数字$\leq 1000000$。

我不会告诉您这是三种写法的双倍经验题!!

一般可以把查区间不同个数改成:$pre_i$表示$i$之前的一个与她相同的数在哪,然后变成查某个区间$pre_i$在某个范围内的数量。可以主席树,也可分块。修改暴力重构。

方法三:带修莫队。按L块为第一关键字、R块为第二关键字、时间为第三关键字对询问排序,这样时间指针的移动复杂度是块数量的平方乘修改数。

理论上块大小取$n^{\frac{2}{3}}$是最好的,但是注意一下修改数只有1000。。于是求个导画个图象(用电脑)可得块大小280左右时最优。加了个离散化跑得飞起。

 //#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
//#include<queue>
//#include<time.h>
//#include<complex>
#include<algorithm>
#include<stdlib.h>
using namespace std; int n,m,lq,lc,tot;
#define maxn 10011
#define maxm 288
int a[maxn],bel[maxn];
struct Ques{int l,r,t,id;}q[maxn];
bool cmp(const Ques a,const Ques b) {return bel[a.l]==bel[b.l]?(bel[a.r]==bel[b.r]?a.t<b.t:a.r<b.r):a.l<b.l;}
struct Modi{int x,a,b;}mo[maxn]; int lisa[maxn<<],li;
int ss; int cnt[maxn<<],ans[maxn];
void modify(int p,int type) {cnt[a[p]]+=type; if (type>) ss+=cnt[a[p]]==; else ss-=cnt[a[p]]==;}
void timemodify(int L,int R,int p,int v) {if (L<=p && p<=R) modify(p,-); a[p]=v; if (L<=p && p<=R) modify(p,);} int main()
{
scanf("%d%d",&n,&lq); m=;
for (int i=;i<=n;i++) bel[i]=(i-)/m+; tot=bel[n];
for (int i=;i<=n;i++) scanf("%d",&a[i]),lisa[++li]=a[i];
char c; lc=;
for (int i=,j=;i<=lq;i++)
{
while ((c=getchar())!='R' && c!='Q');
if (c=='Q')
{
j++; scanf("%d%d",&q[j].l,&q[j].r);
q[j].id=j; q[j].t=lc;
}
else
{
lc++; scanf("%d%d",&mo[lc].x,&mo[lc].b);
mo[lc].a=a[mo[lc].x]; a[mo[lc].x]=mo[lc].b; lisa[++li]=mo[lc].b;
}
}
lq-=lc;
sort(lisa+,lisa++li); li=unique(lisa+,lisa++li)-lisa-;
for (int i=;i<=n;i++) a[i]=lower_bound(lisa+,lisa++li,a[i])-lisa;
for (int i=;i<=lc;i++) mo[i].a=lower_bound(lisa+,lisa++li,mo[i].a)-lisa,
mo[i].b=lower_bound(lisa+,lisa++li,mo[i].b)-lisa; sort(q+,q++lq,cmp);
int L=,R=,T=lc; ss=;
for (int i=;i<=lq;i++)
{
while (T>q[i].t) timemodify(L,R,mo[T].x,mo[T].a),T--;
while (T<q[i].t) T++,timemodify(L,R,mo[T].x,mo[T].b);
while (L<q[i].l) modify(L,-),L++;
while (L>q[i].l) modify(L-,),L--;
while (R<q[i].r) modify(R+,),R++;
while (R>q[i].r) modify(R,-),R--;
ans[q[i].id]=ss;
}
for (int i=;i<=lq;i++) printf("%d\n",ans[i]);
return ;
}

最新文章

  1. JAVA--继承
  2. IDEA 将已有项目添加到git
  3. PowerDesigner连接mysql逆向生成pdm
  4. Java设计模式-建造者模式(Builder)
  5. 第九章 Mass Storage设备
  6. Swift(一,创建对象,类型推导,基本运算,逻辑,字符串,数组,字典)
  7. python 3.5 购物小程序
  8. JavaScript 进阶(四)解密闭包closure
  9. Eclipse格式化代码换行、删除空行
  10. iOS NSString 文本不同的颜色 标题+文本字体大小 行间距/删除不需要的字符 /以及自适应高度
  11. ASP.NET Core MVC中构建Web API
  12. EBS并发程序监控
  13. [模板] 次短路 | bzoj1726-[Usaco2006Nov]Roadblocks第二短路
  14. 月薪15k的测试员需要学习什么技术?
  15. Java线程同步与锁
  16. Appium -选择、操作元素4
  17. python3使用paramiko操作远程机器
  18. SQL Server 统计信息(Statistics)-概念,原理,应用,维护
  19. SSH文件上传代码片段
  20. 20155328 2016-2017-2 《Java程序设计》第三周学习总结

热门文章

  1. 记 thoughtworks 的一次面试
  2. jQuery ajax参数后台获取不到的问题
  3. H5拖拽事件的完整过程和语法
  4. 几个有关整数的证明(from信息安全数学基础的作业)
  5. python基础一 day9 函数升阶(1)
  6. 牛客网练习赛25 C 再编号
  7. maven打包oracle jdbc驱动
  8. git 知识(转)
  9. Tiny4412 U-BOOT移植(转)
  10. 算法导论 第八章 线性时间排序(python)