分块,在每个点记录一下它之前离它最近的相同颜色的位置pre[i],显然问题转化成了求[l,r]中pre[i]<l的值的个数。

这是分块擅长的,在每个块内记录有序表,查询时对零散的暴力,整块的二分即可。

修改时有点麻烦,设修改a[p]。

可能会对pre[p]产生影响;

可能会对p位置之后的第一个 与a[p]修改前相等的值 的pre 产生影响;

可能会对p位置之后的第一个 与a[p]修改后相等的值 的pre 产生影响。

细节蛮多,调了很久。<---蒟蒻。

 #include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,sz,sum,l[],r[],num[],pre[],preb[],a[],x,y,pos[];
int Res,Num;char C,CH[];
inline int G()
{
Res=;C='*';
while(C<''||C>'')C=getchar();
while(C>=''&&C<=''){Res=Res*+(C-'');C=getchar();}
return Res;
}
inline void P(int x)
{
Num=;if(!x){putchar('');puts("");return;}
while(x>)CH[++Num]=x%,x/=;
while(Num)putchar(CH[Num--]+);
puts("");
}
void makeblock()
{
sz=sqrt((double)n*log2(n)); if(!sz) sz=;
for(sum=;sum*sz<n;sum++)
{
l[sum]=(sum-)*sz+;
r[sum]=sum*sz;
for(int i=l[sum];i<=r[sum];i++)
num[i]=sum;
}
l[sum]=sz*(sum-)+;
r[sum]=n;
for(int i=l[sum];i<=r[sum];i++)
num[i]=sum;
}
void makepre()
{
for(int i=;i<=n;i++) {pre[i]=pos[a[i]]; pos[a[i]]=i;}
memcpy(preb,pre,sizeof(pre));
for(int i=;i<=sum;i++) sort(pre+l[i],pre+r[i]+);
}
inline void query()
{
int res=;
if(num[x]+>=num[y]) {for(int i=x;i<=y;i++) if(preb[i]<x) res++;}
else
{
for(int i=x;i<=r[num[x]];i++) if(preb[i]<x) res++;
for(int i=l[num[y]];i<=y;i++) if(preb[i]<x) res++;
for(int i=num[x]+;i<num[y];i++) res+=lower_bound(pre+l[i],pre+r[i]+,x)-(pre+l[i]);
}
P(res);
}
inline void update()
{
int t=;
for(int i=x+;i<=n;i++)
if(a[i]==y)
{*lower_bound(pre+l[num[i]],pre+r[num[i]],preb[i])=x; preb[i]=x;
sort(pre+l[num[i]],pre+r[num[i]]+); break;}
a[]=y;
for(int i=x-;i>=;i--)
if(a[i]==y)
{*lower_bound(pre+l[num[x]],pre+r[num[x]],preb[x])=i; preb[x]=i;
sort(pre+l[num[x]],pre+r[num[x]]+); break;}
int t2=a[x]; a[x]=y;
for(int i=x;i>=;i--)
if(a[i]==t2)
{t=i; break;}
for(int i=x+;i<=n;i++)
if(a[i]==t2)
{*lower_bound(pre+l[num[i]],pre+r[num[i]],preb[i])=t; preb[i]=t;
sort(pre+l[num[i]],pre+r[num[i]]+); break;}
}char op[];
int main()
{
n=G();m=G();
for(int i=;i<=n;i++) a[i]=G();
makeblock(); makepre();
for(int i=;i<=m;i++)
{
scanf("%s",op);x=G();y=G();
if(op[]=='Q') query();
else update();
}
return ;
}

最新文章

  1. java Servlet Filter 拦截Ajax请求
  2. chmod,chown和chgrp的区别
  3. codevs 4163 hzwer与逆序对
  4. 我的Hook学习笔记
  5. 关于java mail 发邮件的问题总结(转)
  6. zf-关于触摸屏子系统(查询机)的页面
  7. 聊一聊JQ中delegate事件委托的好处
  8. SQL Server SubString和charindex的用法
  9. WebService常用接口链接(很全面,值得一看)
  10. [运维工具]linux下远程桌面rdesktop安装和使用
  11. [Swift]LeetCode415. 字符串相加 | Add Strings
  12. 如何从零开始系统化学习视觉SLAM?
  13. 2n字符
  14. Java高级特性 第13节 解析XML文档(1) - DOM和XPath技术
  15. Android开发之如何避免ANR(Keeping Your App Responsive)
  16. CSS 控制鼠标在元素停留的样式
  17. tensorflow降低版本
  18. sqli-labs学习笔记 DAY7
  19. Nginx 是前端工程师的好帮手
  20. 我的QT5学习之路(二)——第一个程序

热门文章

  1. CentOS ninimal 安装后没有桌面-yellowcong
  2. share-Nothing原理
  3. 用npm安装express时报proxy的错误的解决方法
  4. bzoj 2426 【HAOI2010】工程选址 贪心
  5. hive Illegal Operation state transition from CLOSED to ERROR的处理
  6. SpringMVC——说说视图解析器
  7. jquery学习总计
  8. bzoj3779: 重组病毒 link-cut-tree
  9. React module methods with passing props to child or invoking callback to parent.
  10. Django-Django的form表单