洛谷P3396雜湊衝突
阿新 • • 發佈:2018-10-31
傳送門啦
非常神奇的分塊大法。
這個題一看資料範圍,覺得不小,但是如果我們以 $ \sqrt(x) $ 為界限,資料範圍就降到了 $ x < 400 $
我們設陣列 $ f[i][j] $ 表示在 % $ i $ 意義下餘數是 $ j $ 的數的總和。
然後我們以 $ \sqrt(n) $ 為界限,小於 $ \sqrt(n) $ 的直接呼叫陣列,剩下的暴力查詢。修改的話看程式碼吧,真的不難。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int maxn = 150005; inline int read(){ char ch = getchar(); int f = 1 ,x = 0; while(ch > '9' || ch < '0'){if(ch == '-')f = -1; ch = getchar();} while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + ch - '0';ch = getchar();} return x * f; } int n,m,a[maxn],x,y; char flag; long long f[390][390];//表示在 %i 意義下 餘數是 j 的數的總和 int main(){ n = read(); m = read(); for(int i=1;i<=n;i++){ a[i] = read(); for(int j=1;j<=sqrt(n);j++) f[j][i % j] += a[i]; } while(m--){ cin >> flag; x = read(); y = read(); if(flag == 'A'){ if(x * x <= n) printf("%lld\n",f[x][y]); else { int sum = 0; for(int j=y;j<=n;j+=x) sum += a[j]; printf("%d\n",sum); } } else { for(int j=1;j<=sqrt(n);j++) f[j][x % j] += y - a[x]; a[x] = y; } } return 0; }