题解 SP4226 【MSE06H - Japan】(树状数组+逆序对)

原OJ提交点这里

这道题一开始让我很雾......

不过 思路其实非常清晰:如果i<j a[i].x<a[j].x a[i].y>a[j].y 那么就会产生一个交点 大家画个图就出来了

具体操作也很好实现:

定义一个结构体 x升序排列 当x相同就y升序排列

按照我们的排序方式 把a[i].y踢出来跑树状数组求逆序对就可以了

附上AC代码

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1005;
int l,n,m,k,c[1005],a[1005];
long long ans=0;
struct nodee
{
    int x,y;
}qwq[N*N];
int lowbit(int x)
{
    return x&-x;
}
void add(int pos,int x)
{
    for(int i=pos;i<=n;i+=lowbit(i))
    {
        c[i]+=x;
    }
}
int query(int pos)
{
    long long sum=0;
    for(int i=pos;i>=1;i-=lowbit(i))
    {
        sum+=c[i];
    }
    return sum;
}
bool cmp(nodee a,nodee b)
{
    return (a.x<b.x)||((a.x==b.x)&&(a.y<b.y));
}
int main()
{
    scanf("%d",&l);
    for(int i=1;i<=l;i++)
    {
        memset(c,0,sizeof(c));
        memset(a,0,sizeof(a));
        scanf("%d%d%d",&n,&m,&k);
        for(int j=1;j<=k;j++)
        {
            scanf("%d%d",&qwq[j].x,&qwq[j].y);
        }
        sort(qwq+1,qwq+1+k,cmp);
        ans=0;
        for(int j=k;j>=1;j--)
        {
            add(qwq[j].y,1);
            ans+=query(qwq[j].y-1);
        }
    printf("Test case %d: %lld\n",i,ans);
    }
    return 0;
}

最后还是要插两句 我开始的逆序对用了离散化 并且在最后求逆序对跑的顺序 不知道为什么 在luogu,Virtual Judge和POJ都是RE,后来还变成了TLE(好过分嘤嘤嘤) 我不知道这是怎么肥四! 这道题应该可以跑归并 我没有尝试 大家有兴趣可以试试 贴一下我RE的代码 至今不知道错在哪 欢迎大佬指正

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=10005;
int l,n,m,k,c[N],a[N];
long long ans=0;
struct node
{
    int tot,num;
}qaq[N];
struct nodee
{
    int x,y;
}qwq[N];
int lowbit(int x)
{
    return x&-x;
}
void add(int pos,int x)
{
    for(int i=pos;i<=1005;i+=lowbit(i))
    {
        c[i]+=x;
    }
}
int query(int pos)
{
    long long sum=0;
    for(int i=pos;i>=1;i-=lowbit(i))
    {
        sum+=c[i];
    }
    return sum;
}
bool cmp(nodee a,nodee b)
{
    return (a.x<b.x)||((a.x==b.x)&&(a.y<b.y));
}
bool cmpp(node a,node b)
{
    return a.tot<b.tot;
}
int main()
{
    scanf("%d",&l);
    for(int i=1;i<=l;i++)
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int j=1;j<=k;j++)
        {
            scanf("%d%d",&qwq[j].x,&qwq[j].y);
        }
        sort(qwq+1,qwq+1+k,cmp);
        for(int j=1;j<=k;j++)
        {
            qaq[j].tot=qwq[j].y;
            qaq[j].num=j;
        }
        sort(qaq+1,qaq+1+k,cmpp);
        for(int j=1;j<=k;j++)
        {
            a[qaq[j].num]=j;
        }
        ans=0;
        for(int j=1;j<=k;j++)
        {
            add(a[j],1);
            ans+=(j-query(a[j]));
        }
    printf("Test case %d: %lld\n",i,ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/valentino/p/11142296.html

时间: 2024-10-09 23:48:45

题解 SP4226 【MSE06H - Japan】(树状数组+逆序对)的相关文章

hdu 5193 分块 树状数组 逆序对

题意: 给出n个数,a1,a2,a3,...,an,给出m个修改,每个修改往数组的某个位置后面插入一个数,或者把某个位置上的数移除.求每次修改后逆序对的个数. 限制: 1 <= n,m <= 20000; 1 <= ai <= n 思路: 插入和删除用分块来处理,块与块之间用双向链表来维护,每一块用树状数组来求小于某个数的数有多少个. 外层可以使用分块维护下标,这样添加和删除元素的时候,也很方便,直接暴力.查找权值个数时,使用树状数组比较方便.内层通过树状数组维护权值. 每次更新即

Bzoj 2789: [Poi2012]Letters 树状数组,逆序对

2789: [Poi2012]Letters Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 278  Solved: 185[Submit][Status][Discuss] Description 给出两个长度相同且由大写英文字母组成的字符串A.B,保证A和B中每种字母出现的次数相同. 现在每次可以交换A中相邻两个字符,求最少需要交换多少次可以使得A变成B. Input 第一行一个正整数n (2<=n<=1,000,000),表示字符串的长度

Poj 2299 - Ultra-QuickSort 离散化,树状数组,逆序对

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

Codevs 3286 火柴排队 2013年NOIP全国联赛提高组 树状数组,逆序对

题目:http://codevs.cn/problem/3286/ 3286 火柴排队  2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:,其中 ai表示第一列火柴中第 i 个火柴的高度,bi表示第二列火柴中第 i 个火柴的高度.每列火柴中相

【树状数组逆序对】USACO.2011JAN-Above the median

[题意] 给出一串数字,问中位数大于等于X的连续子串有几个.(这里如果有偶数个数,定义为偏大的那一个而非中间取平均) [思路] 下面的数据规模也小于原题,所以要改成__int64才行.没找到测试数据,自己编的几组.简单来说读入每个数,大于等于中位数设为1,小于设为-1,前i个数的和建立一个树状数组,求逆序对. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorit

总结之---树状数组+逆序对问题。

咳咳,这个图必须要的.... 首先,当有一个数组a数量非常大的时候,我们可能改变某个a[i]的值,要求a[n]的和,全部加起来,无疑是要O(n)的时间复杂度. 但是如果n非常大时,O(n)时间复杂度肯定要跪,所以,怎么办的,用神奇的树状数组. 树状数组代码简单,但是非常强大!更令人兴奋的是,它的时间复杂度值需要O(logn)!!! 好了,首先要的东西是把上图的c[n]表示出来,该怎么弄呢,代码如下: int lowbit(int t) { return t&(-t); } 这个代码,简单到爆,但

Codeforces Round #609 (Div. 2)E--K Integers(贪心+二分+树状数组+逆序对)

K Integers 参考博客:https://blog.csdn.net/Q755100802/article/details/103664555 [题意] 给定一个1到n的排列,可以交换相邻的两个元素. 现在定义一个函数f(x),表示在原排列中,通过交换操作,形成一个1,2,3....x的排列的子串,需要的最小操作步骤. 子串意味着这个排列必须是相邻的.现在你需要求出f(1),f(2),f(3)......f(n). [分析] 在1~x这几个元素相邻的情况下,因为最后排列不存在逆序对,根据贪

HDU 2689Sort it 树状数组 逆序对

Sort it Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4110    Accepted Submission(s): 2920 Problem Description You want to processe a sequence of n distinct integers by swapping two adjacent s

HDU - 2838 Cow Sorting (树状数组 + 逆序对)

HDU - 2838 Cow Sorting Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Submit Status Description Sherlock's N (1 ≤ N ≤ 100,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" lev