根號分治做題記錄

2022-09-26 06:24:09 字數 1181 閱讀 7207

對於塊長 \(b=\sqrt n\),對 \(\le b\) 和 \(>b\) 採用其中一種使用暴力,另一種利用 \(\frac n b\le b\) 使用另一種策略。這種方法叫根號分治。

利用基本不等式等等,對 \(b\) 的取值進行平衡,是複雜度最優。

對步長 \(k\) 分類討論。

當 \(k>b\) 時,跳的次數不會超過 \(n/b\),暴力跳,用倍增實現跳 \(k\) 條邊。總 \(o(n\cdot n/b\log n)\)

當 \(k\le b\) 時,考慮對於所有 \(k\) 相同的一起考慮。這個東西顯然是樹上差分類似東西,所以記 \(w_\) 為 \(u\) 的滿足 \(dep\bmod k=val\) 的字首和則對一組 \((s,t,k)\) 的答案等於 \(w_+w_-w_-w_\),如果 \(lca\) 被算了2次就還要再減去 \(lca\) 的不贅述。這個總共 \(o(b\cdot n)\)。

理論最優 \(b=\sqrt\),實測最優 \(b=20\),前者 tle。標算使用長鏈剖分降低複雜度,然而我不會。

#include using namespace std;

const int n=5e4+5;

int n,num,a[n],b[n],c[n],res[n],dep[n],fa[n][17],cnt[225];

vectorg[n],want[n];

map,int>u;

struct jq[n];

inline int read()

void dfs(int x,int p)

void dfsk(int x,int p,int k)

int solve(int s,int t,int k)

for(;dep[t]>=dep[lca];t=tok(t,k))

return sum;

}void print(int x)

int main();

else res[i]=solve(b[i],b[i+1],c[i]);

} sort(q+1,q+num+1,(j a,j b));

for(int i=1,las=1;i<=num;i++)

dfsk(1,0,q[i].k);

for(int j=las;j<=i;j++)

las=i+1;

} }for(int i=1;i}

KMP做題記錄

題目太長不貼了 這道題很巧妙,給定乙個字串s,求最少在首尾新增幾個字元後,s變為乙個迴圈了n次的字串 n 1 假設我們有乙個迴圈串s abcabcabc 我們根據kmp求一次next陣列,就可以通過next strlen s 得到乙個迴圈節的位置從而求出迴圈節的長度,顯然,迴圈節能被s整除。如果s ...

8 25 9 25 做題記錄

2018.8.25 上午 1.ac 洛谷p1514引水入城 搜尋 貪心 2.ac 洛谷p3918 國家集訓隊 特技飛行 貪心 下午 3.ac 洛谷p1120 小木棍 資料加強版 搜尋 剪枝 4.ac 洛谷p1441 砝碼稱重 dfs列舉 01揹包 2018.8.26 上午 參加模擬賽 下午 1.ac...

8 25 9 25 做題記錄

2018.8.25 上午 1.ac 洛谷p1514引水入城 搜尋 貪心 2.ac 洛谷p3918 國家集訓隊 特技飛行 貪心 下午 3.ac 洛谷p1120 小木棍 資料加強版 搜尋 剪枝 4.ac 洛谷p1441 砝碼稱重 dfs列舉 01揹包 2018.8.26 上午 參加模擬賽 下午 1.ac...