zoukankan      html  css  js  c++  java
  • ●CodeForces 429D Trick_Function

    题链:

    http://codeforces.com/problemset/problem/429/D
    题解:

    分治,最近点对
    不难发现g(i,j)=sum[j]-sum[i],
    那么f(i,j)=(i-j)²+(sum[j]-sum[i])²
    =(i-j)²+(sum[i]-sum[j])²
    然后可以把(i,sum[i])看成平面上的点,
    那么要求f(i,j)min就转变为了求平面上的最近点对问题。
    用分治即可解决。

    代码:

    #include<bits/stdc++.h>
    #define MAXN 100005
    #define ll long long
    #define INF 0x3f3f3f3f3f3f3f3fll
    using namespace std;
    struct Point{
    	ll x,y;
    	bool operator < (const Point &rtm) const {
    		return x<rtm.x||(x==rtm.x&&y<rtm.y);
    	}
    }A[MAXN],B[MAXN];
    int N;
    ll sum[MAXN];
    int idx[MAXN];
    ll ABS(ll x){return x<0?-x:x;}
    bool cmpx(const Point &a,const Point &b){return a.x<b.x||(a.x==b.x&&a.y<b.y);}
    bool cmpy(const Point &a,const Point &b){return a.y<b.y||(a.y==b.y&&a.x<b.x);}
    ll dis2(Point &a,Point &b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}
    void build_index(){
    	map<Point,int>M;
    	for(int i=1;i<=N;i++) M[A[i]]=i;
    	for(int i=1;i<=N;i++) idx[i]=M[B[i]];
    }
    ll divide(int l,int r){
    	ll ans=INF;
    	static int tmpidx[MAXN];
    	static Point tmpB[MAXN];
    	if(r-l<=3){
    		for(int i=l;i<=r;i++) for(int j=i+1;j<=r;j++)
    			ans=min(ans,dis2(A[i],A[j]));
    		return ans;
    	}
    	int mid=(l+r)>>1,bl=l,br=mid+1,bnt;
    	for(int i=l;i<=r;i++){
    		if(idx[i]<=mid) tmpB[bl]=B[i],tmpidx[bl++]=idx[i];
    		else tmpB[br]=B[i],tmpidx[br++]=idx[i];
    	}
    	for(int i=l;i<=r;i++) B[i]=tmpB[i],idx[i]=tmpidx[i];
    	ans=min(ans,divide(l,mid));
    	ans=min(ans,divide(mid+1,r));
    	bnt=l; bl=l; br=mid+1;
    	//归并排序
    	while(bl<=mid&&br<=r){
    		if(cmpy(B[bl],B[br])) tmpB[bnt++]=B[bl++];
    		else tmpB[bnt++]=B[br++];
    	}
    	while(bl<=mid) tmpB[bnt++]=B[bl++];
    	while(br<=r) tmpB[bnt++]=B[br++];
    	for(int i=l;i<=r;i++) B[i]=tmpB[i];
    	
    	bnt=1;
    	for(int i=l;i<=r;i++) if(ABS(B[i].x-A[mid].x)<=ans)
    		tmpB[bnt++]=B[i];
    	for(int i=1;i<bnt;i++)
    		for(int j=1;j<=6&&i+j<bnt;j++)
    			ans=min(ans,dis2(tmpB[i],tmpB[i+j]));
    	return ans;
    }
    int main(){
    	scanf("%d",&N);
    	for(int i=1;i<=N;i++){
    		scanf("%lld",&sum[i]);
    		sum[i]+=sum[i-1];
    		A[i]=B[i]=(Point){i,sum[i]};
    	}
    	sort(A+1,A+N+1,cmpx);
    	sort(B+1,B+N+1,cmpy);
    	build_index();
    	ll ans=divide(1,N);
    	printf("%lld
    ",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    股指期货风声水起 股市"蛇人″给我们启示
    Goals of Distributed Application Design
    火箭股票,火箭发射(07.4.12)
    SQLAlchemy完全入门
    巧用异或
    FastAPI启用HTTPS
    错误记录:Can't connect to MySQL server on xxx
    MySQL常用命令
    就是想写点什么
    Android关于Activity class {package/class} does not exist
  • 原文地址:https://www.cnblogs.com/zj75211/p/8541792.html
Copyright © 2011-2022 走看看