时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld

题目描述

众所周知,每个人都有自己的rp值(是个非负实数),膜别人可以从别人身上吸取rp值。

然而当你膜别人时,别人也会来膜你,互膜一段时间后,你们就平分了两人原有的rp值,当你膜过一个人之后,你就不能再膜那个人了

出题人发现自己的rp值为x,出题人周围有n个人,第i个人的rp值为a[i]

你要选择膜哪些人和膜人的顺序,使出题人的最终rp值最大

 

输入描述:


第一行两个数n,x,人数和出题人的初始rp值 第二行n个数,第i个数a[i]表示第i个人的rp值


输出描述:


一行一个数表示出题人的最终rp值(保留三位小数)


示例1

输入

复制


1 0 1


输出

复制


0.500


备注:


数据范围: n<=100000,a[i]<=100000,x<=100000,(a[i],x都是整数)


分析:首先可以要膜比原来大的,比原来值小的直接pass,第二,要按照从小到大排序(举两个值一算就ok)

((x+a)/2+b)/2=(x+a)/4+b/2

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1e5+5;

int n;
double x,a[N];

int main()
{
scanf("%d%lf",&n,&x);
for(int i=1;i<=n;i++)
scanf("%lf",&a[i]);
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)
{
double tmp=(x+a[i])/2.0;
if(tmp>x)
{
x=tmp;
}
}
printf("%.3lf",x);
return 0;
}

B: 出题人的女装

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

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld

题目描述

出题人早上起床就打算穿衣服,他有两箱衣服,因为懒,他在这两天只打算打开一个箱子.

两个箱子中一个有n件衣服,其中有x件女装,另一个有m件衣服,其中有y件女装.

出题人在第一天随机挑一个箱子后,接下来的两天就会从此箱子中随机找一件衣服穿.

又因为出题人懒而且很有钱,所以他穿完衣服后不会去洗,而是直接扔进垃圾桶,也不会放回原来的箱子.

已知出题人第1天穿了女装,求他第二天依然穿女装的概率

 

输入描述:


第一行包含5个整数n,m,x,y,t


输出描述:


若t=0,则在第一行输出概率(四舍五入保留小数点后3位,概率为0输出0.000,概率为100%输出1.000) 若t=1,则在第一行输出概率(最简分数形式,概率为0输出0/1,概率为100%输出1/1)


示例1

输入

复制


10 10 8 8 1


输出

复制


7/9


备注:


2<=n,m<=10000 2<=x<=n且2<=y<=m


贝叶斯公式

官网题解

牛客练习赛38 部分题解_#include

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
ll a[1000000];
ll gcd(ll a,ll b) { return b == 0 ? a : gcd(b, a % b); }
int main()
{
ll n,m,x,y,t;
cin>>n>>m>>x>>y>>t;
if(t==0)
{
double a=x*(x-1)*m*(m-1)+y*(y-1)*n*(n-1);
double b=(n-1)*(m-1)*(x*m+n*y);
printf("%0.3lf\n",a*1.0/b);
}
else{
ll a=x*(x-1)*m*(m-1)+y*(y-1)*n*(n-1);
ll b=(n-1)*(m-1)*(x*m+n*y);

if(a==0){
cout<<"0/1";
}
else if(a==b){
cout<<"1/1";
}else{

ll k=gcd(a,b);
a/=k;
b/=k;
cout<<a<<"/"<<b<<endl;
}
}

return 0;
}

D出题人的手环

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

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld

题目描述

出题人的妹子送了出题人一个手环,这个手环上有 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。


分析:

离散化+树状数组+规律4

但这题和那一题稍微不同,上一题是0~n-1的全排列,所以,没有重复的数,但是这题可能有,所以这题的那个使用规律时,很难确定比某个数大的数有多少,比某个数小的数有多少,我的思路为:num[i]为i的个数(i是离散化后的对应的位置,注意离散化不去重),比他大的个数:n-num[i]-i+1,比他小的数就为i个。

#include<stdio.h>
#include<string>
#include<string.h>
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const int mod=1000000007;

const int MAXN=200000+5;//最大元素个数
int n;//元素个数
ll c[MAXN],a[MAXN];//c[i]==A[i]+A[i-1]+...+A[i-lowbit(i)+1]
ll b[MAXN];
//返回i的二进制最右边1的值
int lowbit(int i)
{
return i&(-i);
}
//返回A[1]+...A[i]的和
ll sum(int x){
ll sum = 0;
while(x){
sum += c[x];
x -= lowbit(x);
}
return sum;
}
//令A[i] += val
void add(int x, ll val){

while(x <= n){
c[x] += val;
x += lowbit(x);
}
}
int num[MAXN];
int main()
{

while(scanf("%d",&n)!=-1)
{

memset(c,0,sizeof(c));
memset(num,0,sizeof(num));
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
b[i]=a[i];
}
sort(b+1,b+n+1);
ll ans=0;
int sum1=1;
for(int i=n;i>0;i--)
{
int pos=lower_bound(b+1,b+n+1,a[i])-b;
num[pos]++;
ans=(ans+sum(pos-1))%mod;
add(pos,1);
}

ll sum=ans;
//cout<<ans<<endl;
for(int i=1;i<n;i++)
{
int pos=lower_bound(b+1,b+n+1,a[i])-b;
ans=(ans+(n-pos-num[pos]+1)-(pos-1)+mod)%mod;///不要忘了+mod
//cout<<a[i]<<" "<<n-pos-num[pos]+1<<" "<<pos-1<<endl;
//cout<<ans<<endl;
sum=(sum*ans)%mod;
}
cout<<sum<<endl;
}
return 0;
}