• 根号分治


    根号分治

    根号算法——不只是分块

    适用类型:长度为(n)的序列,(m)个询问,(n和)(m)通常同阶,显然的方法有(O(n^2))预处理,(O(1))回答,一种是不预处理,

    (O(n))回答(m)个询问,根号分治可以做到(O((n+m)sqrt n))

    luogu P3396 哈希冲突

    (k)开始,每隔(p)个数取一个数,求它们的和

    for(i=k;i<=n;i+=p) ans += value[i];
    

    令答案为(ans[p][k]),模数是(p),余数是(k),对第(i)个数,处理它对ans贡献

    for(p = 1;p <= n;p++) ans[p][i % p] += val[i];
    
    #include<cstdio>
    #include<cmath>
    using namespace std;
    const int S = 150003,N = 403;
    int a[S],f[N][N];//f[i][j]模数是i余数是j 
    int n,m,p,x,y; char e[2];
    inline int read(){
    	int x=0; char c=std::getchar();
    	while(c<'0'||c>'9')c=std::getchar();
    	while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=std::getchar();}
    	return x;}
    int main(){
    	n = read(); m = read(); p = sqrt(n);//pow(n,0.33)更快
    	for(int i = 1;i <= n;i++){
    		a[i] = read();
    		for(int j = 1;j <= p;j++)
    			f[j][i % j] += a[i];
    	}
    	for(int i = 1;i <= m;i++){
    		scanf("%s",e);x = read(); y = read();
    		if(e[0] == 'A'){
    			if(x <= p) printf("%d
    ",f[x][y]);
    			else{
    				int az = 0,j;
    				for(az,j = y;j <= n;j += x)
    				az += a[j];
    				printf("%d
    ",az);
    			}
    		}
    		else{
    			for(int j = 1;j <= p;j++)
    				f[j][x % j] += y-a[x];
    			a[x] = y;
    		}
    	}
    }
    
  • 相关阅读:
    vim 配合管道过滤多行记录
    SpringBoot自动配置原理
    SpringBoot零XML配置的Spring Boot Application
    SpringBoot快速开始Hello World
    Java反射机制
    Java网络编程
    Java JDBC
    Java泛型
    Java I/O
    Java集合
  • 原文地址:https://www.cnblogs.com/shikeyu/p/13491022.html
Copyright © 2020-2023  润新知