HDU 5213 Lucky(容斥原理+莫队算法)
来源:互联网 发布:程序员眼里只有两种人 编辑:程序博客网 时间:2024/06/08 07:58
Lucky
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1230 Accepted Submission(s): 441
Problem Descriptio
WLD is always very lucky.His secret is a lucky number
If WLD can answer all the questions correctly,he'll be the luckiest man in the world.Can you help him?
Input
There are multiple cases.(At MOST
For each case:
The first line contains an integer
The following line contains an integer
The following line contains
The following line contains an integer
The following
Output
For each case:
Print the total of pairs WLD can choose for each question.
Sample Input
53 1 2 1 2 31 1 2 3 5
Sample Output
2Hinta1+a4=a2+a3=3=K.So we have two pairs of numbers (1,4) and (2,3).Good luck!
Source
BestCoder Round #39 ($)
其实读完题,想了一下没有什么优化思路,就想到大概是莫队算法了。
大致题意是给你一个数列{ai},和一个固定的奇数K,然后很多个询问,每个询问给出两个区间[l,r]和[u,v],然后问满足ai+aj=K的数对(i,j)有几对,其中i在区间[l,r]中,j在区间[u,v]中。
虽然说知道了要用莫队,但是实际上,这里一个询问有两个区间,这应该如何应对呢?用两个关键字莫队?后来才知道,此题符合容斥原理。我们考虑一个询问(l,r,u,v)我们可以拆开来看。首先有(l,v),即在整个大区间里面任意取两个a使得等式成立。然后我们考虑这个多计算了什么。由于我们一个数字是[l,r]中取,另一个在[u,v]中取,那么这样计算就多把以下几个部分计算了:一个在[l,r]中,另一个在[r+1,u-1]中;两个都在[l,r]中;一个在[u,v]中,一个在[r+1,u-1]中;两个都在[r+1,u-1]中。两个都在[u,v]中。现在要考虑的就是把多算的减去。前两个部分和最后一部分可以看作一个区间[l,u-1],即在区间中任取;后面三部分可以看作一个区间[r+1,v],即在区间中任取。那么这样就减去了多计算的部分,但是同时又多减去了最后一部分,即两个都在区间[r+1,u-1]中。于是在把这个部分加回去即可。最后总的表达式就是f(l,v)-f(l,u-1)-f(r+1,v)+f(r+1,u-1)。
最后就是莫队的转移了,由于只是两个数字相加,我们可以用一个桶来记录每一个数字出现的次数,如果加入一个数字i,那么产生的贡献就是K-i出现的次数。用莫队的套路去做即可,注意要判断K-i的大小,防止越界。具体见代码:
#include<bits/stdc++.h>#define N 30010using namespace std;struct query{int l,r,sgn,id;} q[N<<2];int n,k,m,tot,blocks,a[N],ans[N];int mp[N];bool cmp(query a,query b){ return a.l/blocks==b.l/blocks?a.r<b.r:a.l/blocks<b.l/blocks;}int main(){ while(~scanf("%d%d",&n,&k)) { blocks=sqrt(n+0.5); tot=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); mp[i]=0; } scanf("%d",&m); for(int i=1;i<=m;i++) { int l,r,u,v; ans[i]=0; scanf("%d%d%d%d",&l,&r,&u,&v); q[++tot]=query{l,v,1,i};//分成四个部分容斥原理 q[++tot]=query{l,u-1,-1,i}; q[++tot]=query{r+1,v,-1,i}; q[++tot]=query{r+1,u-1,1,i}; } sort(q+1,q+tot+1,cmp); int l=1,r=0,res=0; for(int i=1;i<=tot;i++)//莫队基本套路 { while(l<q[i].l) { mp[a[l]]--; if (k>a[l]&&k-a[l]<=n) res-=mp[k-a[l]];//判断K-i是否在范围内 l++; } while(l>q[i].l) { l--; if (k>a[l]&&k-a[l]<=n) res+=mp[k-a[l]]; mp[a[l]]++; } while(r<q[i].r) { r++; if (k>a[r]&&k-a[r]<=n) res+=mp[k-a[r]]; mp[a[r]]++; } while(r>q[i].r) { mp[a[r]]--; if (k>a[r]&&k-a[r]<=n) res-=mp[k-a[r]]; r--; } ans[q[i].id]+=q[i].sgn*res;//sgn表示当前小询问对最后大询问贡献的符号 } for(int i=1;i<=m;i++) printf("%d\n",ans[i]); } return 0;}
- HDU 5213 Lucky(容斥原理+莫队算法)
- [HDU 5213]Lucky:莫队+容斥原理
- hdu 5213 Lucky(莫队算法分块+容斥定理)
- hdu 5213 Lucky(容斥+莫队)
- HDU 5213 Lucky(莫队+容斥)
- hdu5213 Lucky 莫队算法+容斥
- hdu 5213(容斥原理+莫队算法)
- HDOJ 5213 Lucky(分块+莫队+容斥原理)
- HDU 5213 Lucky [莫队+容斥]
- HDU 5213 Lucky 容斥+莫队
- hdu 5213 Lucky (莫队+容斥)
- Lucky - HDU 5213 莫队算法
- hdu 5213 容斥&& 莫队算法
- ZOJ 3233 Lucky Number(容斥原理)
- 【ZOJ】3233【容斥原理】【Lucky Number】
- ZJU 3233 - Lucky Number (容斥原理)
- zoj 3233 Lucky Number(容斥原理)
- hdu 5213 Lucky && 莫队算法的理解
- centos7搭建sftp服务
- Recycleview 侧滑菜单
- 文章标题
- 对象的作用域
- HDU5790-Prefix
- HDU 5213 Lucky(容斥原理+莫队算法)
- 不同类型软件的分析
- 习题6-3 二叉树重建(Tree Recovery, ULM 1997, UVa 536)
- STL源码解析笔记(0)
- Block, 你为啥要 copy?
- bzoj1121 [POI2008]激光发射器SZK
- 四川泡菜中的亚硝酸盐如何变化
- 如何解决Hadoop集群环境下DataNode无法连接NameNode问题
- Elasticsearch5.6.1导入数据并通过Kibana5.6.1展示和查询数据案例学习(上篇)