[codeforces 1311F] Moving Points 离散化+树状数组

Codeforces Round #624 (Div. 3)   比赛人数6075

[codeforces 1311F] Moving Points  离散化+树状数组

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

在线测评地址https://codeforces.ml/contest/1311/problem/F

Problem Lang Verdict Time Memory
F - Moving Points GNU C++11 Accepted 156 ms 5300 KB

//题意总归是理解了
/*
3
1 3 2
-100 2 3

3
d(1,2)=3-1=2,d(1,3)=2-1=1,d(2,3)=0
*/
//如果是O(n^2)的算法,该题比较简单,就是一个简单枚举
//从数据范围看,该题象是O(nlogn)
/*
想了想
xi+vi*t=xj+vj*t
t=(xi-xj)/(vj-vi)
特判vj=vi,d(i,j)=abs(xi-xj)
若t>=0,d(i,j)=0
若t<0,d(i,j)=abs(xi-xj)

算法如下
xi<xj,按坐标自小到大排序
vj-vi>=0   =>   vi<=vj  ans+=abs(xi-xj)
树状数组
*/

//编写过程中,若相关函数不熟悉,记得及时测试。
//发现该题改编自2013 ACM/ICPC Asia Regional Online —— Warmup2
//改编后,难度有较大提升。
// (1≤xi≤10^8),(2≤n≤2⋅10^5).10^8*10^5=10^13 int溢出

STL之unique()去重函数
STL之lower_bound,upper_bound二分查找函数

看了比赛时提交的AC代码,离散化部分,清一色的如下面的代码,请读者重点掌握该离散化代码

#include <cstdio>
#include <algorithm>
#define maxn 200010
#define LL long long
using namespace std;
struct node{
	int loc,v;
}a[maxn];
int n,m,b[maxn];
LL c[maxn],e[maxn];
int cmp(node a,node b){
	return a.loc<b.loc;
}
int lowbit(int x){
	return x&-x;
}
void update(int pos,int delta,LL *d){
	for(int i=pos;i<=n;i+=lowbit(i))d[i]+=delta;
} 
LL sum(int pos,LL *d){
	LL ret=0;
	for(int i=pos;i>0;i-=lowbit(i))ret+=d[i];
	return ret;
}
int main(){
	int i;
	LL ans=0;
	scanf("%d",&n);
	for(i=1;i<=n;i++)scanf("%d",&a[i].loc);
	for(i=1;i<=n;i++)scanf("%d",&a[i].v),b[i]=a[i].v;
	sort(b+1,b+1+n);//离散化开始
	m=unique(b+1,b+1+n)-(b+1);
	for(i=1;i<=n;i++)a[i].v=lower_bound(b+1,b+1+m,a[i].v)-b;//离散化结束
	sort(a+1,a+1+n,cmp);
	for(i=1;i<=n;i++){
		ans+=abs(sum(a[i].v,e)-sum(a[i].v,c)*a[i].loc);//sum(a[i].v,c)统计比vi小的点数量,sum(a[i].v,e)统计比vi小的点坐标和
		update(a[i].v,1,c),update(a[i].v,a[i].loc,e);
	}
	printf("%lld\n",ans);
	return 0;
}
扫描二维码关注公众号,回复: 9428189 查看本文章
发布了553 篇原创文章 · 获赞 531 · 访问量 44万+

猜你喜欢

转载自blog.csdn.net/mrcrack/article/details/104519781