HDU 5792 L - World is Exploding 。容斥原理 + 树状数组 + 离散化
题目,要求找出有多少对这样的东西,四个数,并且满足num[a]<num[b] &&num[c]>num[d]
要做这题,首先要懂得用树状数组,我设,下面的小于和大于都是严格的小于和大于
dpL_min[i]:表示在第i个数往左,(不包括第i个),有多少个数是少于num[i]的
dpL_max[i]:表示在第i个数往左,(不包括第i个),有多少个数是大于num[i]的
dpR_min[i]:表示在第i个数往右,(不包括第i个),有多少个数是小于num[i]的
dpR_max[i]:表示在第i个数往右,(不包括第i个),有多少个数是大于num[i]的
首先我们能预处理出所有的sumab对数,表示在1--n中有多少对这样的ab对。
sumcd同理。然后默认的ans=sumab*sumcd了
但是有重复的呀。有四种情况是重复的,就是a==d || a==c || b==c || a==c
那么,我们枚举每一个i,表示当前是a==d=num[i],就是把a和d现在相同,且数字是num[i],那么要减去的值就是dpR_max[i]*dpL_max[i]; dpR_max[i]表示有多少个数能和num[a]组合,变成num[a]<num[b]的对数。同理dpL_max[i]
再来一个例子吧.。假如现在是a==c=num[i],那么ans -= dpR_max[i] * dpR_min[i]; dpR_max[i] 表示有多少个数能和num[a]组合,变成num[a]<num[b]的对数。dpR_min[i]表示有多少个数能和num[c]结合,变成num[c]>num[d]这样的对数。
这里和网上说的枚举i作为d值是不同的哦,网上的解释我感觉上是说不通的。反正我是想不明白。我这里的枚举每个i,作为他们相同的数子。
有没可能是a==c && b==d呢?可能的,矛盾了。
这里要注意的还有数字是严格大于,在离散的时候注意一下就可以了
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
int n;
const int maxn = + ;
struct data
{
int val,pos;
}book[maxn];
int a[maxn];
int c[maxn];//树状数组
int lowbit (int x)//得到x二进制末尾0的个数的2次方 2^num
{
return x&(-x);
}
void add (int pos,int val)//在第pos位加上val这个值
{
while (pos<=n) //n是元素的个数
{
c[pos] += val;
pos += lowbit(pos);
}
return ;
}
int get_sum (int pos) //求解:1--pos的总和
{
int ans = ;
while (pos)
{
ans += c[pos];
pos -= lowbit(pos);
}
return ans;
}
bool cmp (struct data a,struct data b)
{
return a.val < b.val;
}
int dpL_min[maxn];
int dpL_max[maxn];
int dpR_min[maxn];
int dpR_max[maxn];
void init ()
{
memset(c,,sizeof c);
memset(dpR_max,,sizeof dpR_max);
memset(dpR_min,,sizeof dpR_min);
memset(dpL_max,,sizeof dpL_max);
memset(dpL_min,,sizeof dpL_min);
}
void work ()
{
init();
for (int i=;i<=n;++i)
{
scanf("%d",&book[i].val);
book[i].pos = i;
}
sort(book+,book++n,cmp);
for (int i=;i<=n;++i)
{
if (i>= && book[i].val == book[i-].val) a[book[i].pos] = a[book[i-].pos];
else a[book[i].pos]=i; //从小到大离散
}
for (int i=;i<=n;++i)
{
dpL_min[i] = get_sum(a[i]-);
dpL_max[i] = get_sum(n)-get_sum(a[i]);
add(a[i],);
}
memset(c,,sizeof c);
for (int i=n;i>=;--i)
{
dpR_min[i] = get_sum(a[i]-);
dpR_max[i] = get_sum(n) - get_sum(a[i]);
add(a[i],);
} LL sumab = ;
LL sumcd = ;
for (int i=;i<=n;++i) sumab += dpL_min[i];
for (int i=;i<=n;++i) sumcd += dpL_max[i];
LL ans = sumab * sumcd; for (int i=;i<=n;++i)
{
ans -= dpL_max[i] * dpR_max[i]; //a==d
ans -= dpL_max[i] * dpL_min[i]; // b==d
ans -= dpR_max[i] * dpR_min[i]; // a==c;
ans -= dpL_min[i] * dpR_min[i]; //c==b
}
printf ("%I64d\n",ans);
return ;
}
int main()
{
#ifdef local
freopen("data.txt","r",stdin);
#endif
while(scanf("%d",&n)!=EOF && n) work();
return ;
}
HDU 5792 L - World is Exploding 。容斥原理 + 树状数组 + 离散化的更多相关文章
- HDU 5792:World is Exploding(树状数组求逆序对)
http://acm.hdu.edu.cn/showproblem.php?pid=5792 World is Exploding Problem Description Given a sequ ...
- HDU 5792 World is Exploding(树状数组+离散化)
http://acm.split.hdu.edu.cn/showproblem.php?pid=5792 题意: 思路: lmin[i]:表示左边比第i个数小的个数. lmax[i]:表示左边比第i个 ...
- HDU 2227 Find the nondecreasing subsequences (DP+树状数组+离散化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2227 Find the nondecreasing subsequences ...
- hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点)
hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点) 题意: 给一张无向连通图,有两种操作 1 u v 加一条边(u,v) 2 u v 计算u到v路径上桥的个数 ...
- hdu4605 树状数组+离散化+dfs
Magic Ball Game Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- BZOJ_5055_膜法师_树状数组+离散化
BZOJ_5055_膜法师_树状数组+离散化 Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然 ...
- POJ 2299 【树状数组 离散化】
题目链接:POJ 2299 Ultra-QuickSort Description In this problem, you have to analyze a particular sorting ...
- HDU 5792 World is Exploding (树状数组)
World is Exploding 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5792 Description Given a sequence ...
- HDU 4777 Rabbit Kingdom --容斥原理+树状数组
题意: 给一个数的序列,询问一些区间,问区间内与区间其他所有的数都互质的数有多少个. 解法: 直接搞有点难, 所谓正难则反,我们求区间内与其他随便某个数不互质的数有多少个,然后区间长度减去它就是答案了 ...
随机推荐
- Poj 2328 Guessing Game(猜数字游戏)
一.题目大意 两个小盆友玩猜数字游戏,一个小盆友心里想着1~10中的一个数字,另一个小盆友猜.如果猜的数字比实际的大,则告诉他"too high",小则"too low& ...
- vs2015解决fopen、fscanf 要求替换为fopen_s、fscanf_s的办法
在工程项目设置一下就行:项目属性 -- C/C++-- 预处理器 -- 预处理器定义,添加:_CRT_SECURE_NO_WARNINGS
- C#设计模式(11)——外观模式
一.概念 外观模式提供了一个统一的接口,用来访问子系统中的一群接口.外观定义了一个高层接口,让子系统更容易使用.使用外观模式时,我们创建了一个统一的类,用来包装子系统中一个或多个复杂的类,客户端可以直 ...
- %.*s, printf
%.*s_百度搜索 c语言%.*s是什么_百度知道 *用来指定宽度,对应一个整数 .(点)与后面的数合起来 是指定必须输出这个宽度,如果所输出的字符串长度大于这个数,则按此宽度输出,如果小于,则输出实 ...
- MS-SQL循环、随机数
---创建视图 create view myview as select re=rand() --自定义函数:取得指定范围的随机数 create function mydata( @a int, @b ...
- 元素(Element)和结点(Node)的区别(org.w3c.dom)
1.元素(Element)和结点(Node)的区别, 元素是一个小范围的定义,必须是含有完整信息的结点才是一个元素,例如 - . 但是一个结点不一定是一个元素,而一个元素一定是一个结点. 什么是nod ...
- NIPT需要多大的数据量(reads number)?
NIPT需要多大的数据量(reads number)? 调研 2014 Noninvasive prenatal diagnosis of common aneuploidies by semicon ...
- Python通过调用windows命令行处理sam文件
Python通过调用windows命令行处理sam文件 以samtools软件为例 一.下载或者索取得到windows版本的samtools软件,解压后如下: 进入文件内部,有如下几个文件: 二.将s ...
- Dockerfile设置apt-get install tzdata的noninteractive方法
在Ubuntu系统中,执行命令apt-get install -y tzdata以安装tzdata软件包.但是,最近发现,在Ubuntu 18.04 (Bionic Beaver)上无法自动安装该软件 ...
- p2023&bzoj1798 维护序列
传送门(洛谷) 传送门(bzoj) 题目 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中的一段数全 ...