标签:bit 别人 一个 class get sum int second long
题目描述:n个点有速度,有位置,问所有的点对最小距离之和为多少
解法1:离散化 + 树状数组
基本上做出来的都是用的这个方法,不多介绍,看代码吧
#include<bits/stdc++.h> using namespace std; const int maxn=200010; const int INF=2000000010; typedef long long ll; int n; struct nb { int id, x, v; } a[maxn]; ll num[maxn], sum[maxn]; bool cmp1(nb a, nb b) { return a.x<b.x; } bool cmp2(nb a, nb b) { if(a.v==b.v) return a.x<b.x; else return a.v<b.v; } void add(int x, ll res) { for(int i=x; i<=n; i+=(i&-i)) num[i]++, sum[i]+=res; } ll get_sum(int x) { ll ans=0; for(int i=x; i>0; i-=(i&-i)) ans+=sum[i]; return ans; } ll get_num(int x) { ll ans=0; for(int i=x; i>0; i-=(i&-i)) ans+=num[i]; return ans; } int main() { scanf("%d", &n); for(int i=1; i<=n; i++) scanf("%d", &a[i].x); for(int i=1; i<=n; i++) scanf("%d", &a[i].v); sort(a+1, a+1+n, cmp1); for(int i=1; i<=n; i++) a[i].id=i; sort(a+1, a+1+n, cmp2); ll ans=0; for(int i=1; i<=n; i++) { ans+=get_num(a[i].id)*(ll)a[i].x-get_sum(a[i].id); add(a[i].id, a[i].x); } printf("%lld\n", ans); return 0; }
解法2:
这个解法就很神奇了,AC之后看了一下CF上别人的解法,嗯?怎么这么简洁
略加思索,懂了,妙呀!
先看一下别人的代码,十分简洁
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+10; int n,x[N]; pair<int,int>a[N]; ll ans; int main() { cin>>n; for( int i=0;i<n;i++) { cin>>x[i];a[i].second=x[i]; } for(int i=0;i<n;i++)cin>>a[i].first; sort(a,a+n); sort(x,x+n); for( int i=0;i<n;i++) { ll temp = (i+lower_bound(x,x+n,a[i].second)-x-n+1)*(ll)a[i].second; cout<<temp<<endl; ans+=(i+lower_bound(x,x+n,a[i].second)-x-n+1)*(ll)a[i].second; } cout<<ans; }
因为对于每一个点的坐标,能够用到它的只有两种情况
设这个点坐标为Xn
(1) 坐标在他前面速度比他小的某个点坐标为x0 他们之间的最小距离就是 Xn- X0 了 ans += (Xn - X0)
(2)坐标在他后面速度比他大的某个点坐标为X1 他们之间的最小距离就是X1 - Xn 了 ans += (X1 - Xn)
剩下的情况,最小距离都是0,因为总会追上或者被追上,所以不会对ans产生贡献
那么很显然如果情况(1)的点个数为Y,情况(2)的点个数为X
那么坐标Xn对答案产生的贡献就是(Y-X)*Xn
对于代码中的操作当循环到i的时候
lower_bound(x,x+n,a[i].second)-x就是求它的坐标离散化后是第几个,我们设为p
我们设情况(2)的点有X个,那么在他后面但是速度比她小的点有n-1-p-X个
速度比她小点有i个
情况(1)的点就有Y = i - (n-1-p-X)个
Y - X = i - p - n +1
X被神奇的消掉了,结束。
codeforces 1311F Moving Points 两种解法
标签:bit 别人 一个 class get sum int second long
原文地址:https://www.cnblogs.com/ertuan/p/12918853.html