您的位置:首页 > 运维架构

Wannafly 模拟赛A Laptop 树状数组

2018-04-04 21:09 666 查看
题解:

树状数组+二维偏序。要同时满足i.a>j.a,i.b>j.b才算完虐,然后这道题不想求逆序数那样可以求出多对逆序,这道题只能求出多少个被完虐。所以我们排完第一个序列之后就给编号,然后排序第二个序列,再离散化,然后就进入像计算逆序数那样计算了,但是这里有点不同,因为是要同时满足i.a>j.a,i.b>j.b才算完虐,所以我们从后面开始算,并且如果满足放进去的个数-getsum(e[i])>0就算完虐。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXN=1e5+7;
struct node
{
int val,val2,pos;
}a[MAXN];
int c[MAXN];
int e[MAXN];
int n;
bool cmp1(node b,node d)
{
return b.val<d.val;
}
bool cmp2(node b,node d)
{
return b.val2<d.val2;
}
int lowbit(int x)
{
return x&(-x);
}
void add(int x)
{
for(int i=x;i<=n;i+=lowbit(i))
c[i]++;
}
int getsum(int x)
{
int sum=0;
for(int i=x;i>=1;i-=lowbit(i))
sum+=c[i];
return sum;
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i].val,&a[i].val2);
memset(c,0,sizeof(c));
sort(a+1,a+n+1,cmp1);
for(int i=1;i<=n;i++)
a[i].pos=i;
sort(a+1,a+n+1,cmp2);
for(int i=1;i<=n;i++)
e[a[i].pos]=i,printf("%d %d\n",a[i].pos,a[i].val2);
memset(c,0,sizeof(c));
long long int sum=0;
int x=1;
for(int i=n;i>=1;i--)
{
add(e[i]);
if(x-getsum(e[i]))
sum++;
x++;
}
printf("%lld\n",sum);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: