zoukankan      html  css  js  c++  java
  • CodeForces 540E

    花了近5个小时,改的乱七八糟,终于A了。

    一个无限数列,1,2,3,4,...,n....,给n个数对<i,j>把数列的i,j两个元素做交换。求交换后数列的逆序对数。

    很容易想到离散化+树状数组,但是发现那些没有交换的数也会产生逆序对数,但我没有算。

    经明神提示, 把没有用到的数字段化成点。然后用树状数组算一下就好了。

    然后我用一个数组记录每个点的长度。比如 <1,2><5,6>,1,2,3,4,5,6只有1,2,5,6用到了,那么离散化为1,2,3,4,5,f[1]=f[2]=f[4]=f[5]=1,f[3]=2,数对变为<1,2><4,5>

    莫名有wa了第七组样例,看了数据(捂脸)后改为longlong,有莫名re一发,无脑改了数组长度,然后。。。就a了。。。

    #include <iostream>
    #include <algorithm>
    #include <stdio.h>
    using namespace std;
    
    typedef long long ll;
    
    struct node
    {
        int val;
        int pos;
        bool operator < (const node a) const
        {
            return val < a.val;
        }
    } x[500005];
    
    int a[500005];
    int b[500005];
    int c[500005];
    int d[500005];
    
    int f[500005];
    
    
    int lowbit(int x)
    {
        return x & (-x);
    }
    
    int sum(int n)
    {
    
        int ans = 0;
        while (n > 0)
        {
            ans += c[n];
            n -= lowbit(n);
        }
        return ans;
    }
    
    void update(int pos, int n, int num)
    {
    
        while(pos <= n)
        {
            c[pos] += num;
            pos += lowbit(pos);
        }
    }
    
    int main()
    {
        int n;
        scanf("%d", &n);
    
        for (int i = 0; i < 2 * n; ++i)
        {
            scanf("%d", &x[i].val);
            x[i].pos = i;
        }
        // 离散化
        sort(x, x + 2 * n);
        int cnt = 0;
        for (int i = 0; i < 2 * n; ++i)
        {
            if (i == 0 || x[i].val > x[i - 1].val)
            {
                ++cnt;
                if (x[i].val - x[i - 1].val > 1)
                {
                    f[cnt++] = x[i].val - x[i - 1].val - 1;
                }
                f[cnt] = 1;
            }
            if (x[i].pos & 1)
                b[x[i].pos / 2] = cnt;
            else
                a[x[i].pos / 2] = cnt;
        }
        for (int i = 1; i <= cnt; ++i) d[i] = i;
    
        //交换
        for (int i = 0; i < n; ++i)
        {
            swap(d[a[i]], d[b[i]]);
        }
    
    
        ll ans = 0;
        ll tot = 0;
        for (int i = 1; i <= cnt; ++i)
        {
            ll temp = sum(d[i]);
            ans += (tot - temp) * f[i];
            update(d[i], cnt, f[i]);
            tot += f[i];
        }
    
        printf("%lld", ans);
    
        return 0;
    }
    
    
    /**
    Input:
    5
    2 5
    6 3
    4 6
    5 4
    2 5
    
    2
    1 2
    5 6
    
    output:
    5
    2
    */
    

      

  • 相关阅读:
    numpy 支持切片取值,使用ix_ 也可以取到
    pyinstaller 打包文件成 exe
    matplotlib 直方图概率不为1
    小提琴图 ValueError: object arrays are not supported
    pip 生成 requirements.txt
    CF1515E(连续段 dp)
    Lg7 月赛(构造,树形 dp)
    [省选联考 2020 A 卷] 组合数问题 题解报告
    愤怒的小 N 题解报告
    CF32E 题解
  • 原文地址:https://www.cnblogs.com/wenruo/p/4922231.html
Copyright © 2011-2022 走看看