題解 CF576C 【Points on Plane】
阿新 • • 發佈:2019-01-23
自己的 pan 自己 void using get 距離 tac const 時,
題解 CF576C 【Points on Plane】
一道很好的思維題。
傳送門
我們看這個曼哈頓距離,顯然如果有一邊是按順序排列的,顯然是最優的,那另一邊怎麽辦呢?
假如你正在\(ioi\)賽場上,此時遇到一個\(n\le 10^6\)的題目,你現在發現自己的排列最壞情況是\(O(n^2)\)的,你怎麽辦?
可以莫隊優化!
於是復雜度降到了\(O(n\sqrt{n})\)。
那麽我們回來看,假設點是按\(x\)軸為關鍵字排序的,那麽\(x\)方向產生的貢獻最多是\(n\)的。
那麽,算上\(y\)軸方向上的貢獻,最終的答案是
\(f(n)=n+n\sqrt{n}\)
當\(n\le10^6\)
\(y=f(x),y_{min}=1001000000<2.5\times 10^9\)
於是這題就解決了。上代碼:
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<queue> #include<bitset> #include<vector> #include<map> #include<ctime> #include<cstdlib> #include<set> #include<bitset> #include<stack> #include<list> #include<cmath> using namespace std; #define RP(t,a,b) for(register int (t)=(a),edd_=(b);t<=edd_;++t) #define DRP(t,a,b) for(register int (t)=(a),edd_=(b);t>=edd_;--t) #define ERP(t,a) for(int t=head[a];t;t=e[t].nx) #define Max(a,b) ((a)<(b)?(b):(a)) #define Min(a,b) ((a)<(b)?(a):(b)) #define TMP template<class ccf> #define lef L,R,l,mid,pos<<1 #define rgt L,R,mid+1,r,pos<<1|1 #define midd register int mid=(l+r)>>1 #define chek if(R<l||r<L)return #define all 1,n,1 #define pushup(x) seg[(x)]=seg[(x)<<1]+seg[(x)<<1|1] typedef long long ll; TMP inline ccf qr(ccf k){ char c=getchar(); ccf x=0; int q=1; while(c<48||c>57) q=c==45?-1:q,c=getchar(); while(c>=48&&c<=57) x=x*10+c-48,c=getchar(); if(q==-1) x=-x; return x; } const int maxn=1e6+15; int be[maxn]; int N; int n; struct node{ int x,y,id; inline void scan(int k){ x=qr(1); y=qr(1); id=k; } inline bool operator < (node z){ int dx=z.x; int dy=z.y; if(be[dx]==be[x]){ if(be[dx]&1) return y<dy; else return y>dy; } else return x<dx; } }data[maxn]; int main(){ #ifndef ONLINE_JUDGE freopen("in.in","r",stdin); freopen("out.out","w",stdout); #endif n=qr(1); RP(t,1,n) data[t].scan(t); N=pow(n,0.5); RP(t,1,maxn-15) be[t]=(t-1)/N+1; sort(data+1,data+n+1); RP(t,1,n) cout<<data[t].id<<‘ ‘; cout<<endl; return 0; }
題解 CF576C 【Points on Plane】