codeforces_459D_(线段树,离散化,求逆序数)
链接:http://codeforces.com/problemset/problem/459/D
3 seconds
256 megabytes
standard input
standard output
Parmida is a clever girl and she wants to participate in Olympiads this year. Of course she wants her partner to be clever too (although he's not)! Parmida has prepared the following test problem for Pashmak.
There is a sequence a that consists of n integers a1, a2, ..., an. Let's denote f(l, r, x) the number of indices k such that: l ≤ k ≤ r andak = x. His task is to calculate the number of pairs of indicies i, j (1 ≤ i < j ≤ n) such that f(1, i, ai) > f(j, n, aj).
Help Pashmak with the test.
The first line of the input contains an integer n (1 ≤ n ≤ 106). The second line contains n space-separated integers a1, a2, ..., an(1 ≤ ai ≤ 109).
Print a single integer — the answer to the problem.
7
1 2 1 1 2 2 1
8
3
1 1 1
1
5
1 2 3 4 5
0 题意:f(1,i,ai)表示(1,i)中等于ai的个数,f(j,n,aj)表示(j,n)中与aj相等的个数,求有多少对(i,j)。(特么,之前题意看错了,想了一上午没想明白,结果。。。)
思路:可以用数组fro统计每个位置(包括该位置)其前面有多少个与它相等的数,用beh数组统计每个位置其后有多少个与它相等的数。
样例:
7
1 2 1 1 2 2 1
fro:{1,1,2,3,2,3,4}
beh:{4,3,3,2,2,1,1} 问题就转化为求第一个序列相对第二个序列的逆序数(因为相当于i可以从fro中查看,j可以从beh中查看)
线段树求逆序数。。。
可以从前往后处理,也可以从后往前处理。
貌似从后往前更好理解。
从后往前处理,即,将beh依次插入树中,每插一个,查询其对应的fro的元素(1,fro[i]-1)区间也就是小于fro[i]的个数(查当前树中比fro[i]小的个数)
从前往后跟以上思路相反,插fro查beh(差当前树中比beh[i]大的个数)。
代码中第一次接触到离散化,以后可以借鉴。
此题还需多加理解。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<map>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
struct Node
{
int l,r;
int num;
} tree[<<]; int num[];
int fro[],beh[],sum[];
map<int,int> m1; void build(int l,int r,int rt)
{
tree[rt].l=l;
tree[rt].r=r;
tree[rt].num=;
if(tree[rt].l==tree[rt].r)
return;
int mid=(l+r)/;
build(lson);
build(rson);
} void update(int x,int l,int r,int rt)
{
tree[rt].num++;
if(tree[rt].l==tree[rt].r&&tree[rt].l==x)
return;
int mid=(l+r)/;
if(x<=mid)
update(x,lson);
else
update(x,rson);
} int query(int L,int R,int l,int r,int rt)
{
if(L>R)
return ;
if(L==l&&R==r)
return tree[rt].num;
int mid=(l+r)/;
if(R<mid)
return query(L,R,lson);
else if(L>mid)
return query(L,R,rson);
else
return query(L,mid,lson)+query(mid+,R,rson); }
int main()
{
int n;
scanf("%d",&n);
for(int i=; i<=n; i++)
scanf("%d",&num[i]);
int cnt=;
for(int i=; i<=n; i++) ///离散化,以后可以借鉴
{
if(!m1[num[i]])
m1[num[i]]=cnt++;
num[i]=m1[num[i]];
}
cnt=;
memset(sum,,sizeof(sum));
for(int i=; i<=n; i++)
{
sum[num[i]]++;
fro[i]=sum[num[i]];
cnt=max(cnt,fro[i]);
}
memset(sum,,sizeof(sum));
for(int i=n; i>=; i--)
{
sum[num[i]]++;
beh[i]=sum[num[i]];
}
build(,cnt,);
long long ans=;
for(int i=n; i>; i--)
{
update(beh[i],,cnt,);
//cout<<"**"<<endl;
ans+=query(,fro[i-]-,,cnt,);
//cout<<ans<<'*'<<endl;
}
printf("%I64d\n",ans);
return ;
}
codeforces_459D_(线段树,离散化,求逆序数)的更多相关文章
- 树状数组 && 线段树应用 -- 求逆序数
参考:算法学习(二)——树状数组求逆序数 .线段树或树状数组求逆序数(附例题) 应用树状数组 || 线段树求逆序数是一种很巧妙的技巧,这个技巧的关键在于如何把原来单纯的求区间和操作转换为 求小于等于a ...
- CF 61E 树状数组+离散化 求逆序数加强版 三个数逆序
http://codeforces.com/problemset/problem/61/E 题意是求 i<j<k && a[i]>a[j]>a[k] 的对数 会 ...
- HDU 1394 树状数组+离散化求逆序数
对于求逆序数问题,学会去利用树状数组进行转换求解方式,是很必要的. 一般来说我们求解逆序数,是在给定一串序列里,用循环的方式找到每一个数之前有多少个比它大的数,算法的时间复杂度为o(n2). 那么我们 ...
- POJ 2299 Ultra-QuickSort (树状数组+离散化 求逆序数)
In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a seque ...
- BZOJ 3289 Mato的文件管理(莫队+离散化求逆序数)
3289: Mato的文件管理 Time Limit: 40 Sec Memory Limit: 128 MB Submit: 2171 Solved: 891 [Submit][Status][ ...
- poj1151 Atlanis 线段树+离散化求矩形面积的并
题目链接:http://poj.org/problem?id=1151 很经典的题目,网上有很多模板代码,自己理解了一天,然后很容易就敲出来了... 代码: #include<iostream& ...
- 线段树求逆序数方法 HDU1394&&POJ2299
为什么线段树能够求逆序数? 给一个简单的序列 9 5 3 他的逆序数是3 首先要求一个逆序数有两种方式:能够从头開始往后找比当前元素小的值,也能够从后往前找比当前元素大的值,有几个逆序数就是几. 线段 ...
- [CF 351B]Jeff and Furik[归并排序求逆序数]
题意: 两人游戏, J先走. 给出一个1~n的排列, J选择一对相邻数[题意!!~囧], 交换. F接着走, 扔一硬币, 若正面朝上, 随机选择一对降序排列的相邻数, 交换. 若反面朝上, 随机选择一 ...
- HDU 1394 Minimum Inversion Number (线段树 单点更新 求逆序数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给你一个n个数的序列,当中组成的数仅仅有0-n,我们能够进行这么一种操作:把第一个数移到最 ...
随机推荐
- JAVA编程思想(2) - 操作符(二)
5. 直接常量 -一般来说,假设程序里使用了"直接常量",编译器能够准确的知道要生成什么样的类型.但有时候却是模棱两可的. 这时候须要我们对编译器进行适当的"指导&quo ...
- Codeforces Round #233 (Div. 2)D. Painting The Wall 概率DP
D. Painting The Wall ...
- 为JMenu中的JPopupMenu定制透明背景
最近研究了很久这个问题,从LookAndFeel到继承JPopupMenu或者JMenu都搞不定. 其实替换背景的话,只要在JMenuUI中设置Opaque(false) 再将背景设置透明就可以看到P ...
- arm-linux交叉编译工具链的制作(基于S3C2440)【转】
本文转载自:http://eric-gao.iteye.com/blog/2160622 制作arm-linux交叉编译工具链一般通过crosstool工具或者crosstool-NG,前者使用方便, ...
- 【HDU 2010】水仙花数
http://acm.hdu.edu.cn/showproblem.php?pid=2010 春天是鲜花的季节,水仙花就是其中最迷人的代表,数学上有个水仙花数,他是这样定义的:“水仙花数”是指一个三位 ...
- edittext 底线颜色
<style name="Custom.Widget.EditView" parent="Widget.AppCompat.EditText" > ...
- [odb-users] Create schema error (unknown database schema '')
Boris Kolpackov boris at codesynthesis.comFri May 31 11:13:02 EDT 2013 Previous message: [odb-users] ...
- sql复杂查询语句总结
转自:http://blog.csdn.net/fengfeng91/article/details/15029173 create table student( sno varchar2(10) p ...
- java笔记线程电影院卖票改进版
通过加入延迟后,就产生了连个问题: * A:相同的票卖了多次 * CPU的一次操作必须是原子性的 * B:出现了负数票 * 随机性和延迟导致的 public class SellTicketD ...
- JAVA接口和抽象类的特点
接口的特点: 1:接口不可实例化,可结合多态进行使用(接口 对象=new 对象()) 2:接口里的成员属性全部是以 public(公开).static(静态).final(最终) 修饰符修饰 3:接口 ...