链接

[https://ac.nowcoder.com/acm/contest/358/D]

题意

链接: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,-109<=珠子上的整数<=109。

分析

首先我们知道用树状数组求,逆序数

那么这题由于数据范围是-109<=珠子上的整数<=109。

开一个数组必然是不够的,所以首先离散化一下,就可以求出第一次的逆序数

那么每次变化一个顺序,可以把第一个元素弄到最后,那么逆序数会变为多少呢?

首先对于某个数,求出小于它的数的个数

 int pos1 = lower_bound(d,d+n,a[i+1].va) - d;
x[i] = pos1; //比b[i]小的总个数

以及大于它的数的个数。

int pos2 = upper_bound(d,d+n,a[i+1].va) - d;
y[i] = n - pos2; //比b[i]大的总个数

这里用了lower_bound和upper_bound,

for(int i = 0; i < n; ++i)
{
int pos1 = lower_bound(d,d+n,a[i+1].va) - d;
int pos2 = upper_bound(d,d+n,a[i+1].va) - d;
x[i] = pos1; //比b[i]小的总个数
y[i] = n - pos2; //比b[i]大的总个数
//cout<<x[i]<<' '<<y[i]<<endl;
}

后面遍历剩下乘积取模即可

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1e9+7;
const int N=2e5+10;
int n;
int b[N];
int c[N];
int d[N];
int x[N];
int y[N];
struct node{
int va,pos;
}a[N];
bool cmp(node x,node y){
return x.va<y.va;
}
void update(int i,int va){
for(int j=i;j<=n;j+=j&-j)
c[j]+=va;
}
int getsum(int x){
int ans=0;
for(int i=x;i;i-=i&-i)
ans+=c[i];
return ans;
}
int main(){
//freopen("in.txt","r",stdin);
while(cin>>n){
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++){
cin>>a[i].va;
d[i-1]=a[i].va;
a[i].pos=i;
}
sort(d,d+n);
for(int i = 0; i < n; ++i)
{
int pos1 = lower_bound(d,d+n,a[i+1].va) - d;
int pos2 = upper_bound(d,d+n,a[i+1].va) - d;
x[i] = pos1; //比b[i]小的总个数
y[i] = n - pos2; //比b[i]大的总个数
//cout<<x[i]<<' '<<y[i]<<endl;
}
sort(a+1,a+n+1,cmp);
int cnt=1;
for(int i=1;i<=n;i++){
if(i!=1&&a[i].va!=a[i-1].va)
cnt++;
b[a[i].pos]=cnt;
}
ll sum=0;
for(int i=1;i<=n;i++){
update(b[i],1);
sum+=i-getsum(b[i]);
sum%=mod;
}
//cout<<sum<<endl;
ll ans=sum;
for(int i=0;i<n-1;i++){
sum=((sum-x[i]+y[i])%mod+mod)%mod;
ans=ans*sum%mod;
}
cout<<ans<<endl;
}
return 0;
}

牛客练习赛38 D 出题人的手环的更多相关文章

  1. 牛客练习赛38 E 出题人的数组 2018ccpc桂林A题 贪心

    https://ac.nowcoder.com/acm/contest/358/E 题意: 出题人有两个数组,A,B,请你把两个数组归并起来使得cost=∑i∗ci 最小,归并要求原数组的数的顺序在新 ...

  2. 牛客练习赛42 C 出题的诀窍 (贡献,卡常)

    牛客练习赛42 C 出题的诀窍 链接:https://ac.nowcoder.com/acm/contest/393/C来源:牛客网 题目描述 给定m个长为n的序列a1,a2,-,ama_1 , a_ ...

  3. 牛客练习赛38 D 题 出题人的手环 (离散化+树状数组求逆序对+前缀和)

    链接:https://ac.nowcoder.com/acm/contest/358/D来源:牛客网 出题人的手环 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他 ...

  4. 出题人的女装(牛客练习赛38题B) (概率+分式运算)

    链接:https://ac.nowcoder.com/acm/contest/358/B来源:牛客网 出题人的女装 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他 ...

  5. 牛客练习赛42 C 出题的诀窍

    题目链接:https://ac.nowcoder.com/acm/contest/393/C 这个题就是对于每个数算贡献,如果有相同的数,只计算先出现的数的贡献 对于数x,若它在前i行的数目分别为a1 ...

  6. 出题人的手环(牛客练习赛38D 离散化+树状数组)

    题目链接(https://ac.nowcoder.com/acm/contest/358/D) 题目描述 出题人的妹子送了出题人一个手环,这个手环上有 n 个珠子,每个珠子上有一个数. 有一天,出题人 ...

  7. 最小生成树--牛客练习赛43-C

    牛客练习赛43-C 链接: https://ac.nowcoder.com/acm/contest/548/C 来源:牛客网 题目描述 ​ 立华奏是一个刚刚开始学习 OI 的萌新. 最近,实力强大的 ...

  8. 牛客练习赛48 C 小w的糖果 (数学,多项式,差分)

    牛客练习赛48 C 小w的糖果 (数学,多项式) 链接:https://ac.nowcoder.com/acm/contest/923/C来源:牛客网 题目描述 小w和他的两位队友teito.toki ...

  9. 【并查集缩点+tarjan无向图求桥】Where are you @牛客练习赛32 D

    目录 [并查集缩点+tarjan无向图求桥]Where are you @牛客练习赛32 D PROBLEM SOLUTION CODE [并查集缩点+tarjan无向图求桥]Where are yo ...

随机推荐

  1. css图片垂直水平居中及放大(实现水平垂直居中的效果有哪些方法?)

    实现水平垂直居中方法有很多种: 一.万能法: 1.已知高度宽度元素的水平垂直居中,利用绝对定位和负边距实现. <style type="text/css"> .wrap ...

  2. sql语句中的join用法(可视化解释)

    一.innerjoin innerjoin总结来说就是 ,如A知道通往B如何走:B知道通往C如何走:但是A不知道通往C如何走,但是A可以通过B获得去往C的通往方式.. 首先,假设有A,B两张表,结构及 ...

  3. Scrapy at a glance预览

    1.安装scrapy 2.创建爬虫项目 scrapy startproject test_scrapy 3.创建quotes_spider.py文件4.复制下面代码到quotes_spider.py文 ...

  4. Linux下1号进程的前世(kernel_init)今生(init进程)----Linux进程的管理与调度(六)

    前面我们了解到了0号进程是系统所有进程的先祖, 它的进程描述符init_task是内核静态创建的, 而它在进行初始化的时候, 通过kernel_thread的方式创建了两个内核线程,分别是kernel ...

  5. c/c++ 图的创建及图的相关函数(链表法)

    c/c++ 图的创建及图的相关函数(链表法) 图的概念 图由点和线组成 知道了图中有多少个点,和哪些点之间有线,就可以把一张图描绘出来 点之间的线,分有方向和无方向 创建图 创建图,实际就是创建出节点 ...

  6. 一次线上问题引发的对于C#中相等判断的思考

    线上报来一个问题,说用户的数据丢失了.开发经过紧张的调查.终于找到了原因. if (newData.GetValue(rowIndex) == oldData.GetValue(rowIndex)) ...

  7. C++ 标准 和 C 标准 (截止到2019年03月)

    C++ 标准:维基百科 Year C++ Standard Informal name 1998 ISO/IEC 14882:1998[23] C++98 2003 ISO/IEC 14882:200 ...

  8. Docker: docker image常用命令实战

    #docker列出镜像[root@192 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEnginx latest 881bd08c0b08 ...

  9. 【适合N卡独显电脑的环境配置】Tensorflow教程-Windows 10下安装tensorflow 1.5.0 GPU with Anaconda

    注意: 1.目前Anaconda 更新原命令activate tensorflow 改为 conda activate tensorflow 2. 目前windows with anaconda 可以 ...

  10. SpringBoot的简单登陆开发例子

    1:这个例子用spirngboot整合mybatis,jdbc等技术开发的 2:步骤 2.1:新建一个工程 主要的两个步骤已经贴图了,第二张图是直接在pom.xml文件中加入依赖 2.2:新建完项目, ...