一、Ultra-QuickSort(树状数组求逆序数)

题目链接(点击)

Ultra-QuickSort

Time Limit: 7000MS   Memory Limit: 65536K
Total Submissions: 73943   Accepted: 27692

Description

In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence

9 1 0 5 4 ,

Ultra-QuickSort produces the output

0 1 4 5 9 .

Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.

Input

The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.

Output

For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.

Sample Input

5
9
1
0
5
4
3
1
2
3
0

Sample Output

6
0

思路:

题目表达的很清楚,是想要求输入序列的逆序数(判断序列中的每一位,在之前的数中比该位表示的数大的个数的总和)

例如:

9 1 0 5 4 这个序列

在1前面比1大的有1个 (9) 所以 ans+=1;

在0前面比0大的有两个 (9、1)所以 ans+=2;

同理 ans+=1;ans+=2;

所以ans=6即表示序列的逆序数。

求逆序数的方法如下(暴力):

** 还以上面的序列为例:9 1 0 5 4

给上面每个值按照位置编号从1~5

从第一位开始遍历:先将vis[9]=1;数字9看做位置序号;然后从1开始遍历vis[1]到vis[9]并求和 记录sum=getsum[9];

则 ans+=(i-getsum[9]); 此时i=1,getsum[9]=1(1是因为仅有vis[9]=1); 所以 ans+=(1-1);

往后过程同理;

暴力代码:

肯定会TLE但是可以使用树状数组优化求和过程使O(n²)的复杂度降为O(nlgn);

    for(int i=1;i<=n;i++){
int t=i;vis[a[i]]=1; //整个过程相当于求i-getsum[a[i]];
for(int j=1;j<=a[i];j++){
if(vis[j]==1){
t--;
}
}
ans+=t;
}

**会遇到的问题:

从上面可以知道输入的9看做序号i 但如果9超过数组范围怎么办?

离散化处理:将输入的a[i] 从1开始排列到n 前提是n个数不能重复

例如上面 9 1 0 5 4

离散化结果为:5 2 1 4 3

离散化处理代码:

#include<stdio.h>
#include<algorithm>
using namespace std;
const int MAX=1e5;
struct node{
int count;
int num;
}edge[MAX+5];
bool cmp1(node a, node b)
{
return a.count<b.count;
}
bool cmp2(node a, node b)
{
return a.num<b.num;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&edge[i].count);
edge[i].num=i;
}
sort(edge+1,edge+n+1,cmp1); //按照count大小排序
for(int i=1;i<=n;i++){
edge[i].count=i; //给count重新赋值1~n
}
sort(edge+1,edge+n+1,cmp2); //按照num排序恢复最初大小关系
for(int i=1;i<=n;i++){
printf("%d ",edge[i].count);
}
printf("\n");
return 0;
}

AC代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MAX=5e5;
struct node{
LL i;
LL num;
}edge[MAX+5];
LL n;
LL vis[MAX+5];
bool cmp1(node a, node b)
{
return a.num<b.num;
}
bool cmp2(node a, node b)
{
return a.i<b.i;
}
void add(LL x,LL y)
{
for(LL i=x;i<=n;i+=i&(-i)){
vis[i]+=y;
}
}
LL getsum(LL x)
{
LL ans=0;
for(LL i=x;i>=1;i-=i&(-i)){
ans+=vis[i];
}
return ans;
}
int main()
{
while(~scanf("%lld",&n)&&n){
memset(vis,0,sizeof(vis));
for(LL i=1;i<=n;i++){
scanf("%lld",&edge[i].num);
edge[i].i=i;
}
sort(edge+1,edge+n+1,cmp1);
LL top=1;
for(LL i=1;i<=n;i++){
edge[i].num=top++;
}
sort(edge+1,edge+n+1,cmp2);
LL ans=0;
for(LL i=1;i<=n;i++){
LL t=i;
add(edge[i].num,1);
ans+=(t-getsum(edge[i].num));
}
printf("%lld\n",ans);
}
return 0;
}

二、Cows

题目链接(点击)

Cows

Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 23665   Accepted: 7962

Description

Farmer John's cows have discovered that the clover growing along the ridge of the hill (which we can think of as a one-dimensional number line) in his field is particularly good. 

Farmer John has N cows (we number the cows from 1 to N). Each of Farmer John's N cows has a range of clover that she particularly likes (these ranges might overlap). The ranges are defined by a closed interval [S,E]. 

But some cows are strong and some are weak. Given two cows: cowi and cowj, their favourite clover range is [Si, Ei] and [Sj, Ej]. If Si <= Sj and Ej <= Ei and Ei - Si > Ej - Sj, we say that cowi is stronger than cowj. 

For each cow, how many cows are stronger than her? Farmer John needs your help!

Input

The input contains multiple test cases. 

For each test case, the first line is an integer N (1 <= N <= 105), which is the number of cows. Then come N lines, the i-th of which contains two integers: S and E(0 <= S < E <= 105) specifying the start end location respectively of a range preferred by some cow. Locations are given as distance from the start of the ridge. 

The end of the input contains a single 0.

Output

For each test case, output one line containing n space-separated integers, the i-th of which specifying the number of cows that are stronger than cowi.

Sample Input

3
1 2
0 3
3 4
0

Sample Output

1 0 0

Hint

Huge input and output,scanf and printf is recommended.

思路:

开始做这个题想到的也是暴力(看数据知道会TLE),后来换了思路但又感觉x和y没有关系 会不太好控制,就不知怎么办了

看了讲解:

先将y从大到小排列 这样就保证了后面输入的y值一定是比前面的要小 然后从1遍历数组vis求和便可以得到有多少个符合条件的 然后将所有数加起来便可以得到结果。但是也要注意数据范围是(0 <= S < E <= 105) 有0在里面就没办法使用树状数组求和所以add(x)的时候最好是add(x+1),同时sum(x) 变为 sum(x+1),这样就避免了那种情况。

代码也不是特别麻烦 还要注意while输入 每次使用数组前都要memset一下 初始化数组。

AC代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAX=1e5;
struct node{
int l;
int r;
int num;
}edge[MAX+5];
int vis[MAX+5];
int ans[MAX+5];
bool cmp(node a,node b)
{
if(a.r==b.r){
return a.l<b.l;
}
return a.r>b.r;
}
int sum(int x)
{
int ans=0;
for(int i=x;i>0;i-=i&(-i)){
ans+=vis[i];
}
return ans;
}
void add(int x, int a)
{
for(int i=x;i<=MAX;i+=(i&(-i))){
vis[i]+=a;
}
}
int main()
{
int n;
while(~scanf("%d",&n),n){
memset(vis,0,sizeof(vis));
memset(ans,0,sizeof(ans));
for(int i=0;i<n;i++){
scanf("%d%d",&edge[i].l,&edge[i].r);
edge[i].num=i;
}
sort(edge,edge+n,cmp);
for(int i=0;i<n;i++){
if(i&&edge[i].l==edge[i-1].l&&edge[i].r==edge[i-1].r){
ans[edge[i].num]=ans[edge[i-1].num];
}
else{
ans[edge[i].num]=sum(edge[i].l+1);
}
add(edge[i].l+1,1);
}
for(int i=0;i<n;i++){
if(i==0){
printf("%d",ans[i]);
}
else{
printf(" %d",ans[i]);
}
}
printf("\n");
}
return 0;
}

三、Stars 

题目链接(点击)

Cows

Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 23665   Accepted: 7962

Description

Farmer John's cows have discovered that the clover growing along the ridge of the hill (which we can think of as a one-dimensional number line) in his field is particularly good. 

Farmer John has N cows (we number the cows from 1 to N). Each of Farmer John's N cows has a range of clover that she particularly likes (these ranges might overlap). The ranges are defined by a closed interval [S,E]. 

But some cows are strong and some are weak. Given two cows: cowi and cowj, their favourite clover range is [Si, Ei] and [Sj, Ej]. If Si <= Sj and Ej <= Ei and Ei - Si > Ej - Sj, we say that cowi is stronger than cowj. 

For each cow, how many cows are stronger than her? Farmer John needs your help!

Input

The input contains multiple test cases. 

For each test case, the first line is an integer N (1 <= N <= 105), which is the number of cows. Then come N lines, the i-th of which contains two integers: S and E(0 <= S < E <= 105) specifying the start end location respectively of a range preferred by some cow. Locations are given as distance from the start of the ridge. 

The end of the input contains a single 0.

Output

For each test case, output one line containing n space-separated integers, the i-th of which specifying the number of cows that are stronger than cowi.

Sample Input

3
1 2
0 3
3 4
0

Sample Output

1 0 0

Hint

Huge input and output,scanf and printf is recommended.

思路:

和上面的stars基本一样而且还不需要排序

排序限定了y从小到大 只需要判断x比其小的数目即可

注意:该题目范围还是从0开始 所以要注意add(x) 变为 add(x+1)

同时sum(x) 变为 sum(x+1)

AC代码:

#include<stdio.h>
typedef long long LL;
const int MAX=42000;
struct node{
LL x;
LL y;
LL num;
}edge[MAX+5];
LL vis[MAX+5];
LL ans[MAX+5],flag[MAX+5];
void add(LL x,LL a)
{
for(LL i=x;i<=MAX;i+=i&(-i)){
vis[i]+=a;
}
}
LL sum(int x)
{
LL ans=0;
for(LL i=x;i>0;i-=i&(-i)){
ans+=vis[i];
}
return ans;
} int main()
{
LL n;
scanf("%lld",&n);
for(LL i=0;i<n;i++){
scanf("%lld%lld",&edge[i].x,&edge[i].y);
edge[i].num=i;
}
for(LL i=0;i<n;i++){
if(i&&edge[i].x==edge[i-1].x&&edge[i].y==edge[i-1].y){
ans[edge[i].num]=ans[edge[i-1].num];
}
else{
ans[edge[i].num]=sum(edge[i].x+1);
}
flag[ans[edge[i].num]]++;
add(edge[i].x+1,1);
}
for(LL i=0;i<n;i++){
printf("%lld\n",flag[i]);
}
return 0;
}

Ultra-QuickSort (求逆序数+离散化处理)、Cows、Stars【树状数组】的更多相关文章

  1. 【bzoj3289】Mato的文件管理 离散化+莫队算法+树状数组

    原文地址:http://www.cnblogs.com/GXZlegend/p/6805224.html 题目描述 Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份 ...

  2. poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)

    题目链接:http://poj.org/problem?id=2299 Description In this problem, you have to analyze a particular so ...

  3. poj 2299 树状数组求逆序数+离散化

    http://poj.org/problem?id=2299 最初做离散化的时候没太确定可是写完发现对的---由于后缀数组学的时候,,这样的思维习惯了吧 1.初始化as[i]=i:对as数组依照num ...

  4. POJ 2182 Lost Cows 【树状数组+二分】

    题目链接:http://poj.org/problem?id=2182 Lost Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submis ...

  5. 计蒜客模拟赛D2T2 蒜头君的排序:区间逆序对(移动端点) + 树状数组

    题目链接:https://nanti.jisuanke.com/t/16443 题意: 给你一个由1~n构成的正整数序列,有m组询问,每组询问要求输出[l , r]区间内的逆序对个数. 数据范围: 对 ...

  6. POJ 2481 Cows(树状数组)

                                                                      Cows Time Limit: 3000MS   Memory L ...

  7. [POJ2182]Lost Cows(树状数组,二分)

    题目链接:http://poj.org/problem?id=2182 题意:给定1~n个数和n个位置,已知ai表示第i个位置前有ai个数比当前位置的数小,求这个排列. 和刚才YY的题意蛮接近的,用树 ...

  8. luogu 2154 离散化+杨辉三角+树状数组

    将纵向固定,每次在横向找两个点,计算其中间墓地的贡献答案,离散化后同一行的预处理个数, 树状数组内存储C[up[i]][k] * C[down[i][k] 的值,每次更新时 down[横坐标]++; ...

  9. POJ 2481 Cows 【树状数组】

    <题目链接> 题目大意: 就是给出N个区间,问这个区间是多少个区间的真子集. 解题分析: 本题与stars类似,只要巧妙的将线段的起点和终点分别看成 二维坐标系中的x,y坐标,就会发现,其 ...

随机推荐

  1. Java switch case语句

    switch case 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支. switch case 语句语法格式如下: switch(expression){ case value : ...

  2. poj1966枚举源汇点 求最小点割DInic

    Cable TV Network Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 4854   Accepted: 2241 ...

  3. swiper插件在移动端,多个swiper左右滑动时有空白的问题

    之前在项目上用到了多个swiper.但是结构结构代码css.以及js  几乎一样的除了第一个swiper左右滑动有回弹.其他都没有回弹.于是尝试了各种方法都不行. 百思不得其解 ,最后在官网终于找到了 ...

  4. CF1353E K-periodic Garland(贪心/dp)

    Question 有n盏灯,0代表暗,1代表亮,相邻两个1之间为周期k,求出最少的改变次数 Solution First 贪心方法 详见博客https://blog.csdn.net/cheng__y ...

  5. React Router简单Demo

    简介 react router是使用react的时候首选的一个路由工具. 安装 react router包含react-router,react-router-dom和react-router-nat ...

  6. [256个管理学理论]006.刺猬效应(Hedgehog Effect)

    刺猬效应(Hedgehog Effect) 来自于大洋彼岸的让你看不懂的解释: 刺猬效应(刺猬法则)就是人际交往中的“心理距离效应”.人与人之间都应该保持这条底线,过犹不及. 刺猬效应强调的就是人际交 ...

  7. Jpa使用详解

    目录 ORM思想 1.ORM概述 2.为什么要使用ORM 3.常见的ORM框架 JPA简介 1.JPA概述 2.JPA的优势 3.JPA与hibernate的关系 JPA入门案例 1.搭建开发环境 常 ...

  8. Oracle数据库表被锁死的处理方法

    (1)锁表查询的代码有以下的形式: select count(*) from v$locked_object; select * from v$locked_object; (2)查看哪个表被锁 se ...

  9. Rocket - jtag - JtagTap

    https://mp.weixin.qq.com/s/0u9jM2u-FkTlrk3QNuZaBw 简单介绍JtagTap的实现. 1. 简单介绍 定义TAP(Test Access Port)所需要 ...

  10. Rocket - diplomacy - LazyModuleImpLike

    https://mp.weixin.qq.com/s/gDbUto1qd7uWbpnxovr5pg   介绍LazyModuleImpLike类的实现.     1. wrapper   LazyMo ...