题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5213

莫队算法是离线处理一类区间不修改查询类问题的算法。就是如果你知道了[L,R]的答案。你可以在O(1)的时间下得到[L,R-1]和[L,R+1]和[L-1,R]和[L+1,R]的答案的话。就可以使用莫队算法。

对于莫队算法我感觉就是暴力。只是预先知道了所有的询问。可以合理的组织计算每个询问的顺序以此来降低复杂度。要知道我们算完[L,R]的答案后现在要算[L',R']的答案。由于可以在O(1)的时间下得到[L,R-1]和[L,R+1]和[L-1,R]和[L+1,R]的答案.所以计算[L',R']的答案花的时间为|L-L'|+|R-R'|。如果把询问[L,R]看做平面上的点a(L,R).询问[L',R']看做点b(L',R')的话。那么时间开销就为两点的曼哈顿距离。所以对于每个询问看做一个点。我们要按一定顺序计算每个值。那开销就为曼哈顿距离的和。要计算到每个点。那么路径至少是一棵树。所以问题就变成了求二维平面的最小曼哈顿距离生成树。

关于二维平面最小曼哈顿距离生成树。感兴趣的可以参考点击打开链接

这样只要顺着树边计算一次就ok了。可以证明时间复杂度为n*sqrt(n)这个我不会证明。

但是这种方法编程复杂度稍微高了一点。所以有一个比较优雅的替代品。那就是先对序列分块。然后对于所有询问按照L所在块的大小排序。如果一样再按照R排序。然后按照排序后的顺序计算。为什么这样计算就可以降低复杂度呢。

一、i与i+1在同一块内,r单调递增,所以r是O(n)的。由于有n^0.5块,所以这一部分时间复杂度是n^1.5。
二、i与i+1跨越一块,r最多变化n,由于有n^0.5块,所以这一部分时间复杂度是n^1.5
三、i与i+1在同一块内时变化不超过n^0.5,跨越一块也不会超过2*n^0.5,不妨看作是n^0.5。由于有n个数,所以时间复杂度是n^1.5
于是就变成了O(n^1.5)了。

参考博客:http://blog.csdn.net/bossup/article/details/39236275

解题思路:因为要求的答案满足区间的可加性,我们令f(l,r)表示 l到r这个区间满足条件的ans,令F(l1,r1,l2,r2)为在这两个区间内选取的数满足条件的ans,则根据容斥定理,F(l1,r1,l2,r2)=f(l1,r2)-f(r1+1,r2)-f(l1,l2-1)+f(r1+1,l2-1)。这样就把两个不相关的区间合并成一个可以用莫队算法处理的区间。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;const int maxn = 30005;
int n,m,k,block,a[maxn],cnt[maxn],res[maxn];
struct Query
{int l,r,id,f;bool operator < (const Query rhs) const{if(l / block == rhs.l / block)return r < rhs.r;return l / block < rhs.l / block;}
}q[maxn<<2];void solve()
{block = sqrt(n + 0.5);sort(q,q+(m<<2));int ans = 0,l = 1,r = 0;for(int i = 0; i < (m<<2); i++){while(r > q[i].r){cnt[a[r]]--;if(k - a[r] >= 1 && k - a[r] <= n) ans -= cnt[k-a[r]];r--;}while(r < q[i].r){r++;if(k - a[r] >= 1 && k - a[r] <= n) ans += cnt[k-a[r]];cnt[a[r]]++;}while(l < q[i].l){cnt[a[l]]--;if(k - a[l] >= 1 && k - a[l] <= n) ans -= cnt[k-a[l]];l++;}while(l > q[i].l){l--;if(k - a[l] >= 1 && k - a[l] <= n) ans += cnt[k-a[l]];cnt[a[l]]++;}res[q[i].id] += ans * q[i].f;}
}int main()
{int l1,l2,r1,r2;while(scanf("%d",&n)!=EOF){scanf("%d",&k);for(int i = 1; i <= n; i++){cnt[i] = 0;scanf("%d",&a[i]);}scanf("%d",&m);for(int i = 0; i < m; i++){scanf("%d%d%d%d",&l1,&r1,&l2,&r2);res[i] = 0;q[(i<<2)].l=l1,q[(i<<2)].r=r2,q[(i<<2)].id=i,q[(i<<2)].f=1;  q[(i<<2)+1].l=l1,q[(i<<2)+1].r=l2-1,q[(i<<2)+1].id=i,q[(i<<2)+1].f=-1;  q[(i<<2)+2].l=r1+1,q[(i<<2)+2].r=r2,q[(i<<2)+2].id=i,q[(i<<2)+2].f=-1;  q[(i<<2)+3].l=r1+1,q[(i<<2)+3].r=l2-1,q[(i<<2)+3].id=i,q[(i<<2)+3].f=1;  }solve();for(int i = 0; i < m; i++)printf("%d\n",res[i]);}return 0;
}

hdu 5213(容斥原理+莫队算法)相关推荐

  1. hdu 4358(莫队算法+dfs序列)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4358 解题思路:用dfs求出整棵树的dfs序列,这样以u为根节点的子树就转化到相对应的区间上了.由于是 ...

  2. hdu 5381 2015多校第八场 莫队算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5381 还没学过莫队算法....网上也找不到莫队算法的论文,只能勉强看着别人的代码打下来... 稍微介绍 ...

  3. Hdu 6534 Chika and Friendly Pairs 莫队算法+树状数组

    题目链接 题意求给区间[L,R]中有少对(i,j)满足i<j且abs(a[i]-a[j])<=k. 首先来说暴力的方法就是离散化,然后用树状数组来维护,但是m次询问,m很大,所以说一定会t ...

  4. hdu 5145 NPY and girls (莫队算法)

    题意:有一个长度为n的数字序列,m次询问一个区间l-r中数字重新排列的方案数(mod 10^9+7). 明显的莫队算法,只需要排序,然后预处理一下逆元就可以了. 所谓的莫队算法,最初版本是求曼哈顿距离 ...

  5. [HDU](6333)Problem B. Harvest of Apples ---- 数论+莫队算法

    Problem Description There are n apples on a tree, numbered from 1 to n. Count the number of ways to ...

  6. NBUT 1457 Sona(莫队算法+离散化)

    [1457] Sona 时间限制: 5000 ms 内存限制: 65535 K 问题描述 Sona, Maven of the Strings. Of cause, she can play the ...

  7. XOR and Favorite Number CF340E 莫队算法

    题目链接 题意:求给定询问区间[L,R]问有多少连续区间异或值等k,多次询问可以离线. a[i]^a[i+1]^a[i+2]^a[n]=(a[1]^a[2]^a[3]^...^a[i-1])^(a[1 ...

  8. BZOJ 2038: [2009国家集训队]小Z的袜子(hose)【莫队算法裸题学习笔记】

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MB Submit: 9894  Solved: 4561 [Su ...

  9. 数据结构(莫队算法):国家集训队2010 小Z的袜子

    [题目描述] 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只袜子从1到 ...

最新文章

  1. 计算并显示HOG直方图
  2. java代码简单操作Redis数据Jedis jar
  3. 2019编译ffepeg vs_如何在windows10下使用vs2017编译最新版本的FFmpeg和ffplay
  4. CF1131 G. Most Dangerous Shark(DP+单调栈优化)
  5. Tomcat服务器 Servlet
  6. python核心编程第三版_《Python核心编程(第3版)》
  7. Linux的首次登录操作总结
  8. LeetCode 169. 多数元素 (哈希映射|投票算法)
  9. Oracle中文简繁体转换函数
  10. 05 Java 求职简历制作
  11. 利用MFC和Opencv读取摄像头
  12. php网站设计说课ppt,电子教案5-2网页设计.ppt
  13. 《长安十二时辰》教了哪些算法知识?
  14. mailgun_使用Mailgun API简化应用程序中的电子邮件
  15. WIN32 API串口通信编程
  16. CMake的使用例子
  17. 《读九章算术学Python》如何用Python编程实现盈不足术?附图解分析、代码实现和习题解答
  18. 数据结构-无序(自由)树的简单实现(C++)
  19. 无线仪表变送器设备联网服务器,基于无线HART通信技术的仪表管理与诊断系统的设计.pdf...
  20. su Authentication failure解决方法

热门文章

  1. 数字经济时代,险企如何构建数字化经营体系实现突围?
  2. CEO 赠书 | 甲之蜜糖乙之砒霜,创新者也将成为守旧者
  3. 神策数据全新服务体系——打造用户行为分析领域服务最高标准
  4. JavaScript数组去重算法实例
  5. mybatis出现 Parameter '__frch_excelModel_0' not found.
  6. UML--核心元素之包
  7. websocket与socket.io
  8. Android总结篇系列:Activity Intent Flags及Task相关属性
  9. BI推荐8款优秀的app
  10. iOS开发那些事--编写OCUnit测试方法-逻辑测试方法