zoukankan      html  css  js  c++  java
  • NOIP2013火柴排队

    Solution

    恕我直言,这题是真的坑。

    对于这道题,一个很显然的思路是对于A B两个序列,他们交换完后相对的两个数在原序列中的相对大小是相同的,于是我们就把序列按照A排序,在把B离散化,求逆序对,诶,这题真水。

    期望得分100,实际得分10。

    WTF???我写挂了??

    正解,将A,B分别排序,c[a[i].pos]=b[i].pos,再将c求一波逆序对。

    为什么这样可以,而上一种做法不行?

    随便举个栗子

    2 4 5 6 1 3

    3 4 1 6 5 2

    这是离散化后的序列,我们固定A序列,让B序列动,那么对于B序列来说,3应当在第六个,4应当在2个,1应当在第五个,6应当在第四个,5应当在第三个,2应当在第一个。于是B序列就变成了

    6 2 5 4 3 1

    这就是正解的合理性,而错误解法通过直接排序,将相邻元素的相对顺序打乱了,导致求出的解一定是错的(但是样例都能过【喷血】)。

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define mod 99999997 
    #define N 100009
    using namespace std;
    long long n,tot,tr[N],c[N];
    long long ans;
    struct de
    {
    long long a,b;
    }a[N],b[N]; 
    void add(int u)
    {
    while(u<=n)
    {
    tr[u]++;
    tr[u]%=mod;
    u+=u&-u;
    }
    }
    long long q(int u)
    {
    long long an=0;
    while(u)
    {
    an+=tr[u];
    u-=u&-u;
    }
    return an;
    }
    bool cmp(de a,de b)
    {
    return a.a<b.a;
    }
    int main()
    {
    scanf("%lld",&n);
    for(int i=1;i<=n;++i)
    scanf("%lld",&a[i].a),a[i].b=i;
    for(int i=1;i<=n;++i)
    scanf("%lld",&b[i].a),b[i].b=i;
    sort(a+1,a+n+1,cmp);
    sort(b+1,b+n+1,cmp);
    for(int i=1;i<=n;++i)
    c[a[i].b]=b[i].b;
    for(int i=1;i<=n;++i) 
    {
    (ans+=i-q(c[i])-1)%=mod;
    add(c[i]);
    }
    // for(int i=1;i<=n;++i)
    // cout<<c[i]<<" ";
    cout<<ans;
    return 0;
    }



    最后一句话

    Think twice,code once

  • 相关阅读:
    7月的尾巴,你是XXX
    戏说Android view 工作流程《下》
    “燕子”
    Android开机动画bootanimation.zip
    戏说Android view 工作流程《上》
    ViewController里已连接的IBOutlet为什么会是nil
    My first App "Encrypt Wheel" is Ready to Download!
    iOS开发中角色Role所产生的悲剧(未完)
    UIScrollView实现不全屏分页的小技巧
    Apple misunderstood my app,now my app status changed to “In Review”
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/9389192.html
Copyright © 2011-2022 走看看