博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj1878[SDOI2009]HH的项链
阅读量:7090 次
发布时间:2019-06-28

本文共 1088 字,大约阅读时间需要 3 分钟。

题意:

N个数,M个询问求区间[L,R]中包含了多少种不同的数。

题解:

莫队好像可以做~但正解是树状数组。先将询问按左端点排序,并求出每个数的下一个与它相等的数的位置,同时将每个数第一次出现的位置在树状数组中置为1,此时query(x)求出来的就是1到x里有多少个不同的数。枚举排序后的询问,将当前左端点向右移动,每右移一位就将原位置的数的下一个与它相同的数的位置在树状数组中置为1,保证如果这个数在[l,r]中出现不会漏算。当左端点移动到询问的左端点位置时,就输出query(r)-query(l-1),表示l到r里有多少个不同的数。

代码:

1 #include 
2 #include
3 #include
4 #define inc(i,j,k) for(int i=j;i<=k;i++) 5 #define maxn 50100 6 #define lb(x) x&-x; 7 using namespace std; 8 9 int a[maxn],last[maxn*20],next[maxn],sm[maxn],n,m;10 struct ask{
int l,r,ans,id;}; ask asks[maxn*6];11 bool cmp1(ask a,ask b){
return a.l
0){q+=sm[x],x-=lb(x);} return q;}15 int main(){16 scanf("%d",&n); inc(i,1,n)scanf("%d",&a[i]);17 scanf("%d",&m); inc(i,1,m)scanf("%d%d",&asks[i].l,&asks[i].r),asks[i].id=i;18 memset(last,0,sizeof(last)); inc(i,1,n){
if(last[a[i]])next[last[a[i]]]=i;else update(i,1); last[a[i]]=i;}19 sort(asks+1,asks+1+m,cmp1); int l=1;20 inc(i,1,m){21 while(l

 

20160525

转载于:https://www.cnblogs.com/YuanZiming/p/5698469.html

你可能感兴趣的文章
myeclipse控制台不显示tomcat信息
查看>>
cent os 下载地址
查看>>
SyntaxNet 中文模型的使用
查看>>
对libevent+多线程服务器模型的C++封装类
查看>>
iOS本地数据保存
查看>>
windows下mysql忘记root密码的解决办法
查看>>
[蛋疼]猜测下一波浮点数指数位与小数位的分配
查看>>
cgic程序的编写遇到的问题
查看>>
haproxy url load balancing (url 负载均衡)
查看>>
Radix Tree in Linux Kernel
查看>>
PHP常见错误收集
查看>>
一对多的两个表,查询主表的信息和主表在子表中的记录条数
查看>>
从程序员入门到“第一个项目”的一些事
查看>>
转-Pentaho技术白皮书中文版(三)--构建新组件
查看>>
SpringSrcureCode在grails中实现用户--角色--权限的管理
查看>>
java Servlet 下载 itext 生成的2003 word 文档(java生成word文档3)
查看>>
Delphi 查找标题已知的窗口句柄,遍历窗口控件句柄(转)
查看>>
单例模式
查看>>
最锋利的jQuery源码、电子书及视频教程合集(共46个)
查看>>
JavaScript 内置对象!
查看>>