orz 分塊大爺。思路很神奇也很清晰。
把 塊內最值 和 塊內有序 兩種良好的性質結合起來,非常棒地解決了這個問題。
圖中黑色的樓房即為每個塊內的「可視序列」,顯而易見,在塊內它們的k(斜率)是單增的。
由於上圖中第乙個塊的maxk比後面兩個塊的maxk都要大,所以後兩個塊對答案沒有貢獻,這也是顯然的。這就是維護maxk的意義所在。
否則,若乙個塊可以更新maxk的話,則其中的部分樓房是「可見的」,具體來說,就是在那個比之前的maxk要大的樓房的後面的在可視序列中的樓房數。
另外,並不會像他說的,基本不會t,如果把塊大小開得合適。
1 #include2 #include3 #include4 #include5 #include6using
namespace
std;
7 inline double max(const
double &a,const
double &b)
8 vectorsee[320];9
double k[100001
];10
int sz,sum,l[320],r[320],num[100001
],n,m,x,y;
11double maxv[320
];12
int res,num;char c,ch[12
];13 inline int
g()14
18return
res;19}
20 inline void p(int
x)21
23while(x>0)ch[++num]=x%10,x/=10;24
while(num)putchar(ch[num--]+48
);25 puts(""
);26}27
void
makeblock()
2837 l[sum]=sz*(sum-1)+1
;38 r[sum]=n;
39for(int i=l[sum];i<=r[sum];i++) num[i]=sum;40}
41 inline void
update()
4252
}53 inline void
query()
5462
p(ans);63}
64int
main()
6568
return0;
69 }
BZOJ2957 樓房重建 分塊
貌似是一道線段樹的題,然而線段樹太燒腦想不出來,只能暴力的玩分塊。分塊很好想的,維護 n 個塊,每塊都按照斜率單調遞增的標準來維護。查詢把所有塊for一遍。因為每個塊的斜率都是單調遞增的,對於每個塊使用二分可以節省一點點時間,就可以偷稅 愉悅 的accepted了 玩個斜率就不該用float 就為了...
bzoj 2957 樓房重建 分塊
time limit 10 sec memory limit 256 mb submit 2420 solved 1153 submit status discuss 小a的樓房外有一大片施工工地,工地上有n棟待建的樓房。每天,這片工地上的房子拆了又建 建了又拆。他經常無聊地看著窗外發呆,數自己能夠...
bzoj2957 樓房重建,分塊
分塊沒學過的可以看,分塊入門。題解 把房子分成 n塊每塊裡面維護乙個遞增的子串行,每次更新之後,在每乙個小塊內二分查詢第乙個大於前面最大的斜率,開始斜率為0,每次找完一塊更新一次,暴力加進答案。include include include include include include inclu...