哈希冲突 题解 根号科技
题目传送门
题意
- 给定一个序列,支持单点修改和跳点求和(即
y+kx(k\in N) 的位置上的和)
Sol
2014 年集训队论文 《根号算法——不只是分块》 ——王悦同 例一加强版。
原题是没有修改操作的,但单点修改没有提高本题难度。(
既然都根号算法了那就往根号上想
若
考虑预处理
考虑定义
考虑每个点对
显然
更新与其相同。
总复杂度
\text{Code}
// wish to get better qwq
#include<bits/stdc++.h>
#define re register int
#define pb push_back
using namespace std;
typedef long long ll;
template <typename T> void rd(T &x){
ll fl=1;x=0;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') fl=-fl;
for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
x*=fl;
}
void wr(ll x){
if(x<0) x=-x,putchar('-');
if(x<10) putchar(x+'0');
if(x>9) wr(x/10),putchar(x%10+'0');
}
char op;
inline void getop(){
op=getchar();
while(op!='A'&&op!='C') op=getchar();
}
// ---------- IO ---------- //
const int N=2e5+5,SQ=505;
ll n,m,v[N],len,qaq,qwq;
ll f[N][SQ]; // 当时傻了开大了
inline void modify(ll x,ll y){
for(re i=1;i<=len;i++) f[i][x%i]+=y-v[x];
v[x]=y;
}
inline ll query(ll x,ll y){
if(x<=len) return f[x][y%x];
ll sum=0;
for(re i=y%x;i<=n;i+=x) sum+=v[i];
return sum;
}
// ---------- Sqrt & Operations ---------- //
int main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
rd(n);rd(m);len=(int)sqrt(n);
for(re i=1;i<=n;i++){
int x;rd(x);modify(i,x);
}
while(m--){
getop();rd(qaq);rd(qwq);
if(op=='A') wr(query(qaq,qwq)),puts("");
else modify(qaq,qwq);
}
return 0;
}
// ---------- Main ---------- //
说完这题,我们再来考虑一下论文题。
-
给定一个序列,每次询问给定
x ,y ,问y+kx(k \in N) 的位置上的和。 -
不保证
y\le x