SDOI2017 相關分析

2022-03-31 14:07:33 字數 2534 閱讀 8798

題目傳送門

看了\(loj\) 300多份**,似乎我是唯二寫分塊的?剛開始感覺線段樹比較難寫,就開始碼分塊了。現在知道為什麼沒人寫分塊了……

很容易想到將式子進行拆分,然後維護各種東西:

操作1:\(a = \frac^(x_i * y_i + x_i * \overline + \overline * y_i + \overline * \overline)}^r(x_i^2 + \overline^2 - 2 * x_i * \overline)}\),這個可以通過維護區間\(x_i,y_i\)的和,\(x_i * y_i\)的和來計算。

操作2:\(\forall_ (x_i, y_i) \to (x_i + s, y_i + t)\),這個修改是比較容易的,邊角塊暴力解決,中間塊打標記之後更新區間\(x_i, y_i, x_i * y_i\)的和,具體方法就是吧公式暴力拆開就行了。

操作3:\(\forall_ (x_i, y_i) \to (i + s, i + t)\),這個操作相當與是區間賦值,思想還是一樣的,但是唯一乙個問題就是如何處理邊角塊暴力賦值和區間塊賦值兩個標記的關係。顯然我們乙個塊上的標記是無法下傳的每個元素中的,所以我們需要寫乙個函式來計算當前位置的\(x_i, y_i\)實際為多少。但是區間賦值和邊角暴力賦值的標記又不會合併,所以我們記\(las[i]\)表示第\(i\)個數上一次修改的時間,\(las[i]\)表示第\(i\)個塊上一次修改的時間,這樣我們可以通過比較\(las[i]\)和\(las[bl[i]]\)的值來判斷是以邊角暴力賦的值為準還是整塊賦值為準。之後就沒什麼了。

啊這**真胖……

#include using namespace std;

const int n = 1e5 + 500;

const int sq = 1e3 + 50;

const double inf = 1e16;

int n, m, b, cb, t;

double x[n], y[n], xy[sq], sx[sq], sy[sq], xx[sq], tagx[sq], tagy[sq], cx[sq], cy[sq], sum2[n], las[n], las[n], tagx[n], tagy[n];

int bl[n];

double true(int x, int tp)

else

return ret;

}void modify1(int l, int r, double s, double t)

return ;

} int lb = bl[l], rb = bl[r];

for(int i = l; i <= lb * b; i++)

for(int i = (rb - 1) * b + 1; i <= r; i++)

for(int i = lb + 1; i <= rb - 1; i++)

return ;

}void modify2(int l, int r, double s, double t)

return ;

} int lb = bl[l], rb = bl[r];

for(int i = l; i <= lb * b; i++)

for(int i = (rb - 1) * b + 1; i <= r; i++)

for(int i = lb + 1; i <= rb - 1; i++)

return ;

}double query(int l, int r)

double _x = sumx / (double)(r - l + 1), _y = sumy / (double)(r - l + 1);

double ret = sumxy - sumy * _x;

ret /= (double)(sumxx - _x * sumx);

return ret;

} int lb = bl[l], rb = bl[r];

double sumxy = 0.0, sumxx = 0.0, sumx = 0.0, sumy = 0.0;

for(int i = l; i <= lb * b; i++)

for(int i = (rb - 1) * b + 1; i <= r; i++)

for(int i = lb + 1; i <= rb - 1; i++)

double _x = sumx / (double)(r - l + 1), _y = sumy / (double)(r - l + 1);

double ret = sumxy - sumy * _x;

ret /= (double)(sumxx - _x * sumx);

return ret;

}int main()

cb = bl[n];

for(int i = 1; i <= cb; i++) cx[i] = cy[i] = inf;

while(m--)

else if(tp == 2)

else

} return 0;

}

Sdoi2017 相關分析 線段樹

題意 沙茶線段樹 md其實我考場上還剩乙個多小時寫了40分 其實當時寫正解也可以吧1h也就寫完了不過還要拍一下 正解 比40分短2333 include include include include include using namespace std typedef long long ll ...

Sdoi2017 相關分析 線段樹

題意 沙茶線段樹 md其實我考場上還剩乙個多小時寫了40分 其實當時寫正解也可以吧1h也就寫完了不過還要拍一下 正解 比40分短2333 include include include include include using namespace std typedef long long ll ...

SDOI2017 相關分析(用線段樹維護平方和)

題目啊,這道題目一點思路都沒有啊。這麼神奇的嗎。就是死命的推式子,這裡用一下這位大佬的證明。當然,寫這個部落格主要是想講一下維護平方和和區間加減。首先,區間的 lazy 標記具有可加性 x k k 2 x 2k 2 因此,lazy 標記可以疊加,只要計算每乙個 lazy 標記會對維護的值產生多少的貢...