牛牛看云(二分 or 枚举)
Posted MangataTS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛牛看云(二分 or 枚举)相关的知识,希望对你有一定的参考价值。
题面链接
https://ac.nowcoder.com/acm/contest/23106/H
题面
思路
思路一
对于
∑
i
=
1
n
∑
j
=
i
n
∣
a
i
+
a
j
−
1000
∣
\\sum_i=1^n\\sum_j=i^n |a_i+a_j-1000|
∑i=1n∑j=in∣ai+aj−1000∣这个等式我们会发现,
a
i
a_i
ai的顺序不会对答案造成影响,那么我们很容易想到二分来做,我们先对其排序,然后对每一个i
的位置对
1000
−
a
i
1000-a_i
1000−ai进行二分操作,左半边是负数,右半边是正数,我们统计一下贡献值就好啦
思路二
因为 a i a_i ai的数据范围很小只有[0,1000],我们很显然也能想到用桶排的思想记录每个数出现的次数,然后直接枚举 i , j i,j i,j对即可,这也是出题人的初衷
代码
二分代码
#include<bits/stdc++.h>
using namespace std;
//----------------�Զ��岿��----------------
#define ll long long
#define mod 1000000007
#define endl "\\n"
#define PII pair<int,int>
int dx[4]=0,-1,0,1,dy[4]=-1,0,1,0;
ll ksm(ll a,ll b)
ll ans = 1;
for(;b;b>>=1LL)
if(b & 1) ans = ans * a % mod;
a = a * a % mod;
return ans;
ll lowbit(ll x)return -x & x;
const int N = 2e6+10;
//----------------�Զ��岿��----------------
ll n,m,q,a[N],pre[N];
int main()
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
cin>>n;
for(int i = 1;i <= n ;++i)
cin>>a[i];
sort(a+1,a+1+n);
for(int i = 1;i <= n; ++i)
pre[i] = pre[i-1] + a[i];
ll ans = 0;
for(int i = 1,len = n;i <= n; ++i,len--)
ll l = upper_bound(a+i,a+n+1,1000LL-a[i])-a-1;
ll kk = 1000LL * (l-i+1) - (pre[l]-pre[i-1]) - (l-i+1) * a[i];
ans += kk;
kk = (pre[n]-pre[l]) - 1000LL * (n-l) + (n-l) * a[i];
ans += kk;
cout<<ans<<endl;
return 0;
枚举代码
#include<bits/stdc++.h>
#define ll unsigned long long
using namespace std;
const int maxn=1e6+10;
int n,a[maxn];ll ans;
int num[1001];
int main()
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);num[a[i]]++;
ll cnt;
for(int i=0;i<=1000;i++)
for(int j=i;j<=1000;j++)
if(i==j)
cnt=num[i]+(num[i]*(num[i]-1ll))/2ll;
else
cnt=num[i]*num[j];
ans+=cnt*(ll)abs(i+j-1000);
cout<<ans;
return 0;
以上是关于牛牛看云(二分 or 枚举)的主要内容,如果未能解决你的问题,请参考以下文章