Little Sub and Counting【思维】
程序员文章站
2022-07-15 16:19:46
...
题目描述
Little Sub likes Math. Now he has a simple counting problem for you.
Given an positive integer sequence A, for each Ai , Please calculate how many elements Aj in the sequence satisfi ed AiAj > AjAi .
输入
The first line contains one positive integer n(1 ≤ n≤100000).
The following line contains n positive integers Ai(1≤Ai≤231-1).
输出
Please output n integer in one line and separate them by a single space. The ith integer indicates the answer concerning AiAj > AjAi ..
样例输入
3 1 2 5
样例输出
0 2 1
题目分析:题目大意是给你一组数找出符合Ai的Aj次幂大于Aj的Ai次幂的个数有几个。现在我们假设Ai等于啊Aj等于b,则可以推导出一个表达式即为f(x)=(Inx)/x;所以就转化为就比这个数小的数有多少个,那么我们可以对这个表达式求一下导看看他的增减性。求完显然可以看出是以x=e 为分界线的先增再减的一个函数,更加巧合得是 x=2 与 x=4 的函数值相等,这就很便于我们变、编程求解它了。推导过程如下:
代码如下:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
typedef long long ll;
struct node{
ll a;
ll b;
ll dis;
}edge[200000];
ll vis[200000];
bool cmp(node x,node y)
{
return x.a<y.a;
}
bool cmp1(node x,node y)
{
return x.b<y.b;
}
int main()
{
ll n;
scanf("%lld",&n);
ll k1=0,k2=0,k3=0,k4=0;
for(ll i=1;i<=n;i++)
{
scanf("%lld",&edge[i].a);
edge[i].b=i;
if(edge[i].a==1)
k1++;
else if(edge[i].a==2)
k2++;
else if(edge[i].a==3)
k3++;
else if(edge[i].a==4)
k4++;
}
sort(edge+1,edge+1+n,cmp);
for(ll i=n;i>=1;i--)
{
if(edge[i].a!=edge[i+1].a)
{
edge[i].dis=n-i;
edge[i].dis+=k1;
}
else
edge[i].dis=edge[i+1].dis;
}
//printf("%lld %lld %lld \n",k1,k3,k4);
for(ll i=1;i<=n;i++)
{
if(edge[i].a==1)
edge[i].dis=0;
else if(edge[i].a==2)
edge[i].dis=edge[i].dis-k3-k4;
else if(edge[i].a==3)
edge[i].dis=edge[i].dis+k2;
else if(edge[i].dis==4)
edge[i].dis=edge[i].dis;
else
break;
}
sort(edge+1,edge+1+n,cmp1);
for(ll i=1;i<=n;i++)
printf(i==n?"%lld\n":"%lld ",edge[i].dis);
return 0;
}