POJ_3067 Japan[ 逆序数 树状数组 or 归并排序)

传送门:POJ_3067

题目:n,m,k;左右两列数,数的范围分别1-n,1-m,然给k个连线。

Sample Input

1
3 4 4
1 4
2 3
3 2
3 1

Sample Output

Test case 1: 5

思路:逆序数

代码:

//树状数组版

//块状数组

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<string>
#include<map>
#include<vector>
#include<queue>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define mem(a,b) memset(a,b,sizeof a)
#define read_ freopen("i.txt","r",stdin)

using namespace std;

typedef long long LL;
const int N=1010;
int n,m,k;
int c[N];

struct node{
    int a,b;
}p[1000010];

int cmp(node a,node b)
{
    if(a.a==b.a)
        return a.b<b.b;
    return a.a<b.a;
}

int lowbit(int x)
{
    return x&(-x);
}

void add(int x,int v)
{
    while(x<=m)
    {
        c[x]+=v;
        x+=lowbit(x);
    }
}

LL sum(int x)
{
    LL ret=0;
    while(x>0)
    {
        ret=ret+c[x];
        x-=lowbit(x);
    }
    return ret;
}

int main()
{
    int T;
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++)
    {
        mem(c,0);
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<k;i++)
            scanf("%d%d",&p[i].a,&p[i].b);
        sort(p,p+k,cmp);
        LL ans=0;
        for(int i=0;i<k;i++){
            add(p[i].b,1);
            ans+=sum(m)-sum(p[i].b);
        }
        printf("Test case %d: %I64d\n",cas,ans);
    }
    return 0;
}
时间: 2024-10-06 21:44:03

POJ_3067 Japan[ 逆序数 树状数组 or 归并排序)的相关文章

HPU1291 小朋友排队 【逆序数+树状数组】

1291: 小朋友排队 时间限制: 1 Sec  内存限制: 128 MB 提交: 2  解决: 1 [提交][状态][讨论版] [Edit] 题目描述 n 个小朋友站成一排.现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个小朋友. 每个小朋友都有一个不高兴的程度.开始的时候,所有小朋友的不高兴程度都是0. 如果某个小朋友第一次被要求交换,则他的不高兴程度增加1,如果第二次要求他交换,则他的不高兴程度增加2(即不高兴程度为3),依次类推.当要求某个小朋友第k次交换时,他的不高

hdu 1394 Minimum Inversion Number 逆序数/树状数组

Minimum Inversion Number Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1394 Description The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai

POJ 2299 Ultra-QuickSort(逆序数 树状数组)

Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 45960   Accepted: 16702 Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swappin

zoj 3157 Weapon 逆序数/树状数组

B - Weapon Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Description In World War 3, your countries' scientists have invented a special weapon. Assume that the enemy's city can be described by rectangular co

求逆序数模板(树状数组+离散化 || 归并排序法)

一篇不错的讲解:http://www.cnblogs.com/shenshuyang/archive/2012/07/14/2591859.html 代码如下:(树状数组+离散化) #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn=500017; int n; int aa[maxn

POJ 2299 Ultra-QuickSort (树状数组or 归并排序分治求逆序对数)

题目大意就是说帮你给一些(n个)乱序的数,让你求冒泡排序需要交换数的次数(n<=500000) 显然不能直接模拟冒泡排序,其实交换的次数就是序列的逆序对数. 由于数据范围是 0 ≤ a[i] ≤ 999,999,999所以先要离散化,然后用合适的数据结果求出逆序 可以用线段树一步一步添加a[i],每添加前查询前面添加比它的大的有多少个就可以了. 也可用树状数组,由于树状数组求的是(1...x)的数量和所以每次添加前查询i-sum(a[i])即可 树状数组: //5620K 688MS #incl

POJ - 2299 - Ultra-QuickSort = 归并排序 + 逆序对 / 树状数组

http://poj.org/problem?id=2299 求逆序对最简单的绝对不会是树状数组,一定是归并排序(认真),不过树状数组会不会快一点呢?理论上应该是树状数组快一点(假如不进行离散化). #include<algorithm> #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<map> #include<set

BZOJ3295 CQOI2011 动态逆序对 树状数组套线段树

离线倒着做,每次加入一个节点后新增的逆序对数量就是其左边大于它的数的个数(左边数的总数-左边小于它的数的个数)+右边小于它的数的个数 用树状数组维护求和,对于树状数组中每个节点v所对应的区间线段树维护区间[l,r]中大于v的数的个数. 最后唯一的问题就是指针版线段树MLE-- #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <alg

求逆序对[树状数组] jdoj

求逆序对 题目大意:给你一个序列,求逆序对个数. 注释:n<=$10^5$. 此题显然可以跑暴力.想枚举1到n,再求在i的后缀中有多少比i小的,统计答案即可.这显然是$n^2$的.这...显然过不去,我们思考如何优化?显然,这里的有些过程是重复的.我们将这个序列设为a序列,对于两个1到n中的整数i<j,在j后面的数我们进行了多次重复枚举,我们思考如何优化.容易想到用一个桶来记录.只需要记录对于每一个数来讲,我后面有多少个数是比我小的,只需要将桶中的数累加即可.但是,我们必须记录是这个数之后的桶