BIT (树状数组) ——Poj 3067 Japan

###题目: Poj 3067 Japan

### 题解:

1.求逆序对
2.bit
3.先排前端,再排后端,提取后端序列
4.wrong 到发疯~~~

for (LL u = f[i]; u <= M; u += u & ((-1)*u)) c[u] ++;

void add(LL i, LL x)
{
    while (i <= M)//注意M而不是K或N
    {
        bit[i] += x;
        i += i & -i;
    }
}

###AC代码:

####解1

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#define  maxn   1000000 + 10

using namespace std;
typedef long long LL;
int f[maxn],c[maxn];
int N,M,K;
struct P{
	int w;
	int e;
};
P  cnt[maxn];
bool cmp ( const P &a,const P &b)
{
	if (a.w == b.w)  return a.e < b.e;
	else  return a.w < b.w;
}

int main()
{
	int T;
	cin >> T;
	for (int t = 1; t <= T; t++)
	{
	    scanf("%d%d%d",&N,&M,&K);
	    for(int k = 0; k < K; k++)
	       scanf("%d%d",&cnt[k].w,&cnt[k].e);

            sort (cnt,cnt+K,cmp);

	    memset (c,0,sizeof(c));

	    int num = 0;
	    LL ans = 0;

	    for (int i = 0; i < K; i++)
	    {
	        num ++;
		    f[num] = cnt[i].e;
        }

	    for (int i = 1; i <= num; i++)
	    {
            ans += i - 1;
		    for (LL u = f[i];u > 0; u -= u & ((-1)*u))  ans -= c[u];

		    for (LL u = f[i]; u <= M; u += u & ((-1)*u)) c[u] ++;
	    }
            printf("Test case %d: %lld\n",t,ans);
	}
	return 0;
}

####解2

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>


using namespace std;
typedef long long LL;
const int  maxn = 1000000 + 10;
LL bit[1010];
LL n;
LL N,M,K;
struct P{
	LL w;
	LL e;
};
P  cnt[maxn];
bool cmp (P a,P b)
{
	if (a.w == b.w)  return a.e < b.e;
	else  return a.w < b.w;
}
LL sum(LL i)
{
    LL s = 0;
    while(i > 0)
    {
        s += bit[i];
        i -= i & -i;
    }
    return s;
}
void add(LL i, LL x)
{
    while (i <= M)
    {
        bit[i] += x;
        i += i & -i;
    }
}
int main()
{
	LL T;
	cin >> T;
	for (LL t = 1; t <= T; t++)
	{


        memset(cnt,0,sizeof(cnt));
	    scanf("%I64d%I64d%I64d",&N,&M,&K);

	    for(LL i = 1; i <= K; i++)
	       scanf("%I64d%I64d",&cnt[i].w,&cnt[i].e);

        sort (cnt+1,cnt+K+1,cmp);

	    LL ans = 0;

        memset (bit,0,sizeof(bit));

        n = K;
	    for (LL i = 1; i <= n; i++)
	    {
            ans += i - 1 - sum(cnt[i].e);
            add(cnt[i].e,1);
	    }
            printf("Test case %I64d: %I64d\n",t,ans);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值