質問の意味:あなたは今横に与えられたn点されているあなたは、R間隔の3行を描きましょうその後、縦に3線を描画するには、同じ距離rである今、あなたは後に最もポイントを見つけてみましょう
アイデア:私たちは、最初の行のy間隔にツリーを構築した後、x軸は、各更新ポイント重なっ列挙し、その後、戻って、最大更新を見つけます
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 constの ダブル PI = ACOS( - 1.0 )。 CONSTの INT N = 1E5 + 7 。 const int型 INF = 0x3f3f3f3f 。 constの ダブル EPS = 1E- 6 。 typedefの長い 長いLL。 CONST LL MOD = 1E7 + 9 。 int型nは、D; 構造体ツリー{ int型のL、R。 LL V; } T [N << 4 ]。 int型 YY [N << 2]; ベクター < INT > XX [N << 2 ]。 ボイド押し上げ(INT P){ T [P] .V = MAX(T [P << 1 ] .V、T [P << 1 | 1 ] .V)。 } ボイドビルド(int型 P、int型の L、INT R){ T [P] .L = L。T [P] .R = R。 もし(L == R){ T [P] .V = YY [L] + YY [L + D] + YY [L + 2 *のD]。 返します。 } INT半ば=(L + R)>> 1 。 P(ビルド<< 1 、L、MID)。 構築した(p << 1 | 1、ミッド+ 1 、R); 突き上げ(P); } ボイド更新(int型 P、int型のx、int型のval){ もし(T [P] .L ==さt [P] .R && T [P] .L == X){ T [P] .V + = ヴァル。 返します。 } INT半ば=(T [P] .L + T [P] .R)>> 1 。 もし(x <= MID)更新(P << 1 、X、ヴァル)。 他の更新(P << 1 | 1 、X、val)で、 突き上げ(P); } ボイドワーク(int型のx、int型のval){ 更新(1 、X、ヴァル)。 もし(XD> = 0)更新(1、XD 、ヴァル)。 もし(X- 2 * D> = 0)更新(1、X- 2 *のD、ヴァル)。 } int型のmain(){ IOS :: sync_with_stdio(偽)。 cin.tie(0)。cout.tie(0 )。 CIN >> N >> D。 int型の痘= 0 ; int型 POY = 0; 以下のために(int型 i = 1 ; iが++; iが<= N ){ int型 X、Y。CIN >> X >> Y。 痘 = MAX(ポックス、X)。POY = MAX(POY、Y)。 YY [Y] ++ ; XX [X] .push_back(Y)。 } ビルド(1、0 、POY)。 LL ANS = 0 。 以下のために(int型 i = 0 ; I <=ポックス; iは++ ){ LLのTMP = XX [I] .size()+ XX [I + D] .size()+ XX [I + 2 * D] .size()。 以下のための(int型J = 0 ; J <XX [I] .size(); J ++ ){ ワーク(XX [I]、[J]、 - 1 )。 } のための(int型 J = 0 ; J <XX [I + D] .size(); J ++ ){ 作業は(xxは[iが + D] [j]は、 - 1 )。 } のための(INT J = 0 ; J <XX [I + 2 * D] .size(); J ++ ){ ワーク(XX [I + 2 *のD] [j]は、 - 1 )。 } ANS = MAX(ANS、T [ 1 ] .V + TMP)。 以下のための(int型J = 0 ; J <XX [I] .size(); J ++ ){ ワーク(XX [I]、[J]、1 )。 } のための(int型 J = 0 ; J <XX [I + D] .size(); J ++ ){ 作業は(xxは[iが + D] [j]は、1 )。 } のための(INT J = 0 ; J <XX [I + 2 * dの] .size(); J ++ ){ ワーク(XX [I + 2 *のD] [J]、1 ); } } COUT << ANS << ENDL。 }