• 出题人的手环


    链接: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;
    }
    
    
    
     
     
  • 相关阅读:
    ScheduledThreadPoolExecutor源码解读
    Spring事务源码阅读笔记
    Spring AOP的实现研究
    cglib之Enhancer
    Spring IOC容器创建bean过程浅析
    CompletionService简讲
    Spring Boot:关于“No converter found for return value of type: class xxx”的解决方法
    java关于Date转换成字符串格式以及Date的增加
    jsp中文乱码六种情况---解决方案
    MYSQL给表添加字段
  • 原文地址:https://www.cnblogs.com/liuzuolin/p/10828777.html
Copyright © 2020-2023  润新知