蒟蒻刚学树状数组,35分求助

P1908 逆序对

Small_Tang @ 2021-04-29 13:20:44

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
#define lowbit(w) w&(-w)
using namespace std;
int read()
{
    int r=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){r=r*10+ch-'0';ch=getchar();}
    return r*f;
}
int n;
LL ansl=0,s[1100000];
struct node{int x,y;}a[1100000];
bool cmp(node x,node y){return x.x>y.x;}
void change(int w)
{
    while(w<=n)
    {
        s[w]++;
        w+=lowbit(w);
    }
}
LL sum(int w)
{
    LL ans=0;
    while(w>0)
    {
        ans+=s[w];
        w-=lowbit(w);
    }
    return ans;
}
int main()
{
    freopen("1.in","r",stdin);
    n=read();
    for(int i=1;i<=n;i++){a[i].x=read();a[i].y=i;}
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++)
    {
        change(a[i].y);
        ansl+=sum(a[i].y-1);
    }
    printf("%lld",ansl);
    return 0;
}

by Small_Tang @ 2021-04-29 13:22:39

第六个点本地运行是对的,交上去就错了……


by Mr_WA的大号 @ 2021-04-29 13:51:11

呃,这题是归并排序吧?


by 子丑 @ 2021-04-29 14:05:55

@Mr_WA的大号 树状数组可以写,而且更短(


by YukiChyan @ 2021-04-29 15:16:51

@Summery freopen?


by Mr_WA的大号 @ 2021-04-29 16:50:32

@子丑 谢谢告知,请问怎么用树状数组写?


by 子丑 @ 2021-04-29 16:58:39

@Mr_WA的大号

这道题数据范围比较大,所以先离散化一下,不然树状数组存不下;然后可以从后往前扫一遍,每个数字都丢到树状数组里,再询问一下比它小的数,把结果加到答案里。

由于我们是反着扫的,这些比它小的数的下标必定比它要大。


by 子丑 @ 2021-04-29 16:59:41

@Summery 注意数据范围……数字最大1e9,用树状数组得先离散化一遍


by Mr_WA的大号 @ 2021-04-29 16:59:52

@子丑 蟹蟹dalao


by Small_Tang @ 2021-04-30 12:21:59

@子丑 谢,不过我是存下标的(a[i].y)


by Small_Tang @ 2021-04-30 12:22:45

@YukiChyan 调试时候加的,不是这个错


| 下一页