zoukankan      html  css  js  c++  java
  • 出题人的手环

    链接:https://ac.nowcoder.com/acm/contest/358/D
    来源:牛客网

    题目描述

    出题人的妹子送了出题人一个手环,这个手环上有 n 个珠子,每个珠子上有一个数。
    有一天,出题人和妹子分手了,想把这个手环从两个珠子间切开,并按顺时针顺序展开成一条链。
    可以发现,这条链一共有 n 种可能性。求这 n 种可能性的逆序对数之积模 1000000007。

    输入描述:

    第一行一个数 n,表示珠子个数。
    接下来一行 n 个数,以顺时针顺序给出每个珠子上的整数

    输出描述:

    一个数,表示答案。
    示例1

    输入

    复制
    4
    1 3 2 3

    输出

    复制
    24

    说明

    一共有 4 种方式:
    1 3 2 3;3 1 3 2;2 3 1 3;3 2 3 1;
    逆序对数分别为 1,3,2,4,积为 24。

    备注:

    n<=200000,-10^9<=珠子上的整数<=10^9。
    题意:中文题
    思路:计算出原始序列的逆序对(sum),转换后的通过观察我们可以得出将一个数移到序列最后它的逆序对变化为sum=sum+序列中大于a[1]的数-序列中小于a[1]的数。
    代码:
    #include<bits/stdc++.h>
    #define mod 1000000007
    using namespace std;
    const int maxn=2e5+5;
    int n;
    int t[maxn],c[maxn],pmin[maxn],pmax[maxn];
    vector<int> v,nv;
    int getid(int x){
        return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
    }
    int lowbit(int x){
        return x&(-x);
    }
    void add(int x){
        while(x<=n){
            c[x]++;
            x+=lowbit(x);
        }
    }
    int query(int x){
        int ans=0;
        while(x>0){
            ans+=c[x];
            x-=lowbit(x);
        }
        return ans;
    }
    int main(){
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&t[i]);
            v.push_back(t[i]);
            nv.push_back(t[i]);
        }
        sort(v.begin(),v.end());
        sort(nv.begin(),nv.end());
        for(int i=0;i<n;i++){
            int u=lower_bound(v.begin(),v.end(),t[i])-v.begin();//第一个大于等于t[i]的数
            //cout<<u<<endl;
            if(v[u]==t[i]){
                int vi=upper_bound(v.begin(),v.end(),t[i])-v.begin();
                pmin[i]=u;
                pmax[i]=(n-vi);//cout<<pmin[i]<<" "<<pmax[i]<<endl;
            }else{
                pmin[i]=u;
                pmax[i]=(n-u);
            }
    
        }
        v.erase(unique(v.begin(),v.end()),v.end());
        long long sum=0;
        for(int i=0;i<n;i++){
            int u=getid(t[i]);
            add(u);
            sum+=(i+1)-query(u);
        }
        cout<<sum<<endl;
        long long ans=sum;
        for(int i=0;i<n-1;i++){
            sum=(sum+pmax[i]+mod-pmin[i])%mod;
            cout<<sum<<endl;
            ans=(ans*sum)%mod;
        }
        printf("%lld
    ",(ans+mod)%mod);
        return 0;
    }
    
    
    
     
     
  • 相关阅读:
    NOIP simulation
    NOIP2013
    BZOJ 4176 Lucas的数论
    BZOJ 3512 DZY Loves Math IV
    BZOJ 3994 Sum
    BZOJ 4174 tty的求助
    BZOJ 3561 DZY Loves Math VI
    BZOJ 2508 简单题/BZOJ 3775 点和直线
    FTR #1 百步穿杨
    BZOJ 4407 于神之怒加强版
  • 原文地址:https://www.cnblogs.com/liuzuolin/p/10828777.html
Copyright © 2011-2022 走看看