codeforces 459D D. Pashmak and Parmida's problem(离散化+线段树或树状数组求逆序对)
题目链接:
D. Pashmak and Parmida's problem
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[l,r,x]=在a[l],a[l+1]...a[r]中有多少个a[i]等于x,这道题可以问f[1,i,a[i]]>f[j,n,a[j]]&&1<=i<j<=n的i和j的对数,令pre[i]为a[i]在区间[1,i]中出现的次数,同理nex[j]为a[j]为区间[j,n]中a[j]出现的次数,结果就变成了求sigma{pre[i]和nex[i+1]的逆序对数}i为1到n-1;这时不是单单的一个数组求逆序对数(一个数组求逆序对数可以在归并排序中解决),所以得用线段树或者树状数组,树状数组还不会,等学会了树状数组再来更树状数组的代码;
AC代码:
/*~~~~~~~~线段树的代码~~~~~~~~~~~~~*/
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+;
int n,a[N],pre[N],nex[N];
struct nod
{
int l,r,sum;
};
nod tree[*N];
void build(int node,int le,int ri)
{
tree[node].l=le;
tree[node].r=ri;
tree[node].sum=;
if(le==ri)return ;
int mid=(le+ri)>>;
build(*node,le,mid);
build(*node+,mid+,ri);
tree[node].sum=tree[*node].sum+tree[*node+].sum;
}
int query(int node,int L,int R)
{
if(L<=tree[node].l&&R>=tree[node].r)
{
return tree[node].sum;
}
int mid=(tree[node].l+tree[node].r)>>;
if(R<=mid)return query(*node,L,R);
else if(L>mid)return query(*node+,L,R);
else return query(*node,L,R)+query(*node+,L,R);
}
int update(int node,int num)
{
if(tree[node].l==tree[node].r&&tree[node].l==num)
{
tree[node].sum+=;
return ;
}
int mid=(tree[node].l+tree[node].r)>>;
if(num<=mid)update(*node,num);
else update(*node+,num);
tree[node].sum=tree[*node].sum+tree[*node+].sum;
}
map<int,int>mp1,mp2;
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
mp1[a[i]]++;
pre[i]=mp1[a[i]];//用map进行离散化
}
for(int i=n;i>;i--)
{
mp2[a[i]]++;
nex[i]=mp2[a[i]];
}
long long ans=;
build(,,n+);//建树时建到n+1,避免后面的nex[i]+1>n;
for(int i=;i<=n;i++)
{
if(nex[i]!=n)
ans+=(long long)query(,nex[i]+,n);
update(,pre[i]);
}
cout<<ans<<"\n";
return ;
}
/*~~~~~~~~树状数组的代码~~~~~~~~~~为什么用树状数组还没有线段树的快?*/
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+;
int n,a[N],pre[N],nex[N],sum[N];
int lowbit(int x)
{
return x&(-x);
}
void update(int x)
{
while(x<=n)
{
sum[x]++;
x+=lowbit(x);
}
}
int query(int x)
{
int s=;
while(x>)
{
s+=sum[x];
x-=lowbit(x);
}
return s;
}
map<int,int>mp1,mp2;
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
mp1[a[i]]++;
pre[i]=mp1[a[i]];
}
for(int i=n;i>;i--)
{
mp2[a[i]]++;
nex[i]=mp2[a[i]];
}
long long ans=;
for(int i=n;i>;i--)
{
ans+=(long long)query(pre[i]-);
update(nex[i]);
}
cout<<ans<<"\n";
return ;
}
codeforces 459D D. Pashmak and Parmida's problem(离散化+线段树或树状数组求逆序对)的更多相关文章
- codeforces 540E 离散化技巧+线段树/树状数组求逆序对
传送门:https://codeforces.com/contest/540/problem/E 题意: 有一段无限长的序列,有n次交换,每次将u位置的元素和v位置的元素交换,问n次交换后这个序列的逆 ...
- 【Codeforces 459D】Pashmak and Parmida's problem
[链接] 我是链接,点我呀:) [题意] 定义两个函数 f和g f(i)表示a[1..i]中等于a[i]的数字的个数 g(i)表示a[i..n]中等于a[i]的数字的个数 让你求出来(i,j) 这里i ...
- codeforces 459 D. Pashmak and Parmida's problem(思维+线段树)
题目链接:http://codeforces.com/contest/459/problem/D 题意:给出数组a,定义f(l,r,x)为a[]的下标l到r之间,等于x的元素数.i和j符合f(1,i, ...
- Codeforces Round #261 (Div. 2) D. Pashmak and Parmida's problem (树状数组求逆序数 变形)
题目链接 题意:给出数组A,定义f(l,r,x)为A[]的下标l到r之间,等于x的元素数.i和j符合f(1,i,a[i])>f(j,n,a[j]),求i和j的种类数. 我们可以用map预处理出 ...
- Codeforces Round #301 (Div. 2) E . Infinite Inversions 树状数组求逆序数
E. Infinite Inversions ...
- CodeForces 459D Pashmak and Parmida's problem
Pashmak and Parmida's problem Time Limit:3000MS Memory Limit:262144KB 64bit IO Format:%I64d ...
- cf459D Pashmak and Parmida's problem
D. Pashmak and Parmida's problem time limit per test 3 seconds memory limit per test 256 megabytes i ...
- codeforces D. Pashmak and Parmida's problem
http://codeforces.com/contest/459/problem/D 题意:给你n个数,然后统计多少组(i,j)使得f(1,i,ai)>f(j,n,aj); 思路:先从左往右统 ...
- codeforces459D:Pashmak and Parmida's problem
Description Parmida is a clever girl and she wants to participate in Olympiads this year. Of course ...
随机推荐
- 转:MSSQL SERVER行转列 列转行
SQL Server中行列转换 Pivot UnPivot PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PI ...
- Shiro 认证失败返回JSON
Shiro框架默认认证失败后会返回到登录页面,在前后端分离项目中,需要返回JSON数据,以便前端或者app端解析处理. 实现方式: 1. 扩展shiro框架的UserFilter类,重写redirec ...
- hihocoder1260,1261 (HASH经典题)
这两题比赛做的时候各种卡,太久没有写过这种类型的题目了.各种细节想不清楚. 赛后看下网上大部分题解的代码,发现大部分都是直接用TRIE+暴力直接搞的--!,随便找了份代码发现有些数据这种做法是超时的, ...
- java.util包下面的类---------01---示意图
一直在使用util包下面的这些类,甚至有些没用过的,想要都去认识认识他们!也许在未来的一天可以用到! 图太大不好截图!部分没有截全!
- Arrays类--Arrays.asList()方法使用
java.util类 Arrays java.lang.Object——java.util.Arrays public class Arrays extends Object 此类包含用来操作数组(比 ...
- RxJava2 源代码解析(一)
转载请标明出处: http://blog.csdn.net/zxt0601/article/details/61614799 本文出自:[张旭童的博客](http://blog.csdn.net/zx ...
- inux c编程:读写锁
前面介绍的互斥量加锁要么是锁状态,要么就是不加锁状态.而且只有一次只有一个线程可以对其加锁.这样的目的是为了防止变量被不同的线程修改.但是如果有线程只是想读而不会去写的话,这有不会导致变量被修改.但是 ...
- [闲来无事,从头再来][C51篇]导读
目 的: 通过学习C51,熟悉单片机,熟悉C语言,熟悉单片机系统的外部电路. 方 法: 通过看书和使用板子做实验来进行学习 参考资料: <新概念51单片机C语言教程& ...
- 教你使用SQL查询(1-12)
教你使用 Select 查询语句 (1) SELECT 语句基本语法简介 http://jimshu.blog.51cto.com/3171847/1363101(2) TOP 和 OFFSET 筛选 ...
- ABAP服务器文件操作
转自http://blog.itpub.net/547380/viewspace-876667/ 在程序设计开发过程中,很多要对文件进行操作,这又分为对本地文件操作和服务器文件操作.对本地文件操作使用 ...