1. 程式人生 > >NK分治賽題解

NK分治賽題解

右上角 long 轉化 while brush ges pre 最小 amp

A-航運調度:

一道比較裸的三分題,令$F(t)$為$t$時刻船兩兩之間距離的最大值,直接三分求$F(t)$在$[0,+\infty)$的最小值即可。

時間復雜度:$O(n^2 log n)$。

(其實你問我為什麽它是個單峰函數我也不會證)

B-防線:

首先有一個顯然的結論,如果$x$處有破綻,那麽包含$x$的區間的防具和一定是奇數。於是乎在$[1,2^{31}-1]$上二分即可找到有破綻的位置。

求$[a,b]$上防具和時僅需將所有的部署都掃一遍。

sum=0;
for(i=1;i<=n;i++) {
	sum+=(b-S[i])/D[i]+1;
	if(a-1>=S[i]) sum-=(x-1-S[i])/D[i]+1;
}

l=1;r=(1<<31)-1;
while(l<r) {
  m=l+r>>1;
  if(getSum(l,m)&1) r=m;
  else l=m+1;
}

  

核心代碼如上,直抄必錯。註意判斷。

時間復雜度:$O(NTlog(2^{31}-1))=O(NT)$

C-分形之城:

其實只要把圖看懂了這道題還是很好想的。

技術分享

顯然每個等級都可以分成四塊,每塊裏面的編號是連續的。

設每個等級的城區為$T_k$,$k$為等級。我們要求編號為$i$的街區在$T_k$中的位置$(x,y)$,可以想辦法先求出$i$在它所在的塊中的位置,也就是$T_{k-1}$中的位置$(x‘,y‘)$,再想辦法求$(x,y)$。至此我們已經把問題規模縮小了。現在的問題是如何把$(x‘,y‘)$轉化為$(x,y)$。

為討論方便,我們令$(x,y)$指的是從左上角算起

,第$x$行第$y$列的街區編號為$i$。

那麽分情況討論。

  • 若$i$在左上角的塊中。

    計數也是從左上角開始的,但方向翻轉了一下,所以

    $(x,y)=(y‘,x‘)$

  • 若$i$在右上角的塊中。

    其實這跟原來是完全沒區別的,僅需平移一下。

    $(x,y)=(x‘,y‘+len)$

  • 若$i$在右下角的塊中。

    同上,有

    $(x,y)=(x‘+len,y‘+len)$

  • 若$i$在左下角的塊中。

    這個要麻煩一點,它是從右下角開始計數的,但也不難推出

    $(x,y)=(len*2+1-y‘,len+1-x‘)$

討論清楚了就很好實現了。($len$為其中一塊的邊長)

但這道題有不少坑點,首先編號什麽的要開$long \ \ long$。而且不能先乘10再算距離否則$long \ \ long$會溢出,此處感謝[email protected]$。(如果你用$double$當我沒說)

時間復雜度:$O(NT)$

NK分治賽題解