博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
luogu P1972 [SDOI2009]HH的项链 树状数组
阅读量:6895 次
发布时间:2019-06-27

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

之前只做过分块做法,补一下树状数组做法。

我们先考虑一个问题,如何求从[1,x]这一区间内元素不同的个数?显然我们只要从到到位,遇到一个新的元素,就在对应位置+1,然后使用树状数组求前缀和即可。

这里我们需要去求[x,y],所求区间的左端点也会发生变化。我们先按照[1,x]的方法预处理出这个前缀和数组。我们考虑对询问区间按照左端点排序。然后对于当前的区间[x0,y0],query(y0) - query(x0 - 1)与正确答案相比有所区别,是因为有些元素在x0左侧计算过了,而在这段区间中,对应第一次出现的位置没有+1。我们考虑能不能弥补这个错误呢。我们预处理出nxt[i],表示与位置i元素相同的右侧最近元素的下标。这样子,比如上一个区间为[x1,y1],下一个区间为[x2,y2],那么我们就让[x1,x2)这段区间中的每一个i的nxt[i]位置都对应+1。如果nxt[i]在[x1,x2)内,则不会对以后的答案造成影响,如果nxt[i]在[x2,]后,则显然修正了这个错误,并且在[i,x2)这段区间中,不会再有相同的元素了。

忘记了树状数组的lowbit x & (-x)必须有括号。

1 #include 
2 #include
3 #include
4 using namespace std; 5 struct qry 6 { 7 int l,r,id; 8 friend bool operator < (qry a,qry b) 9 {10 return a.l < b.l;11 }12 } vec[510000];13 int n,m;14 int num[510000],nxt[510000],hav[1100000],res[510000],sum[510000];15 int lowbit(int x)16 {17 return x & (-x);18 }19 void tre_insert(int x,int val)20 {21 for (int i = x;i <= n;i += lowbit(i))22 sum[i] += val;23 }24 int tre_qry(int x)25 {26 int tot = 0;27 for (int i = x;i;i -= lowbit(i))28 tot += sum[i];29 return tot;30 }31 int main()32 {33 scanf("%d",&n);34 for (int i = 1;i <= n;i++) 35 scanf("%d",&num[i]);36 scanf("%d",&m);37 for (int i = 1;i <= m;i++)38 {39 scanf("%d%d",&vec[i].l,&vec[i].r);40 vec[i].id = i;41 }42 sort(vec + 1,vec + m + 1);43 for (int i = 1;i <= n;i++)44 if (hav[num[i]] == 0)45 {46 hav[num[i]] = 1;47 tre_insert(i,1);48 }49 memset(hav,0,sizeof(hav));50 for (int i = n;i >= 1;i--)51 {52 if (hav[num[i]] == 0)53 nxt[i] = n + 1;54 else55 nxt[i] = hav[num[i]];56 hav[num[i]] = i;57 } 58 int t = 1;59 for (int i = 1;i <= m;i++)60 { 61 for (;t <= vec[i].l - 1;t++)62 tre_insert(nxt[t],1);63 res[vec[i].id] = tre_qry(vec[i].r) - tre_qry(vec[i].l - 1);64 }65 for (int i = 1;i <= m;i++)66 printf("%d\n",res[i]);67 return 0;68 }

 

转载于:https://www.cnblogs.com/iat14/p/10507586.html

你可能感兴趣的文章
如何使用 Log4j
查看>>
DevOps 工程师成长日记系列一:必备知识与技能组合
查看>>
足球队(党) 动态规划 DP (这道题我做不动,残念)
查看>>
[BZOJ1296][SCOI2009]粉刷匠(DP)
查看>>
python beautifulsoup爬虫
查看>>
Eclipse中syso 快捷键 Alt + / 不能使用的问题
查看>>
vim利器:vundle 管理器和NERDTree插件
查看>>
一些链接资源
查看>>
Swift 笔记3
查看>>
手势解锁,就这么简单
查看>>
CSS“隐藏”元素的几种方法的对比
查看>>
Executor执行框架
查看>>
[FMX] Android APP 启动黑屏优化补丁
查看>>
常用JavaScript的高级技巧
查看>>
bzoj 1670: [Usaco2006 Oct]Building the Moat护城河的挖掘
查看>>
摘抄:Java多线程学习
查看>>
mysql 不同索引的区别和适用情况总结
查看>>
Html5使用canvas作图线宽很粗
查看>>
[转]Ubuntu下ROS开发环境搭建(QT+ros_qtc_plugin)
查看>>
iOS. PercentEscape是错用的URLEncode,看看AFN和Facebook吧
查看>>