zoukankan      html  css  js  c++  java
  • P3396 哈希冲突

    P3396 哈希冲突(根号分治)

    像这样的题大多可以考虑根号分治,也就是和模数有关的。

    我们对于询问的值来分治:

    对于小于 (sqrt{n}) 的模数:

    说明剩余系也不超过 (sqrt{n}) 个,于是我们可以预处理这样的询问,需要时直接回答即可。

    预处理时间复杂度是 (O(nsqrt{n})) 的,询问 (O(1))

    对于大于等于 (sqrt{n}) 的模数:

    每个剩余系里面的元素不超过 (sqrt{n}) 个。

    于是对于每一个询问,我们可以直接枚举起点,然后不断地累加这个剩余系里面下标的答案即可。

    这部分询问是 (O(sqrt{n})) 的,时间复杂度是 (O(msqrt{n}))

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    template <typename T>
    inline void read(T &x){
    	x=0;bool f=false;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
    	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    	x=f?-x:x;
    	return ;
    }
    template <typename T>
    inline void write(T x){
    	if(x<0) putchar('-'),x=-x;
    	if(x>9) write(x/10);
    	putchar(x%10^48);
    	return ;
    }
    const int N=1e5+5e4+5,M=405,INF=1e9+7;
    int n,m,t,a[N];
    int sum[M][M];//摸i时第j个池子的情况 
    int main(){
    	read(n),read(m);t=sqrt(n);
    	for(int i=1;i<=n;i++) read(a[i]);
    	for(int i=1;i<=t;i++) for(int j=1;j<=n;j++) sum[i][j%i]+=a[j];
    	for(int i=1,x,y;i<=m;i++){
    		char op[5];
    		scanf("%s",op);read(x),read(y);
    		if(op[0]=='A'){
    			if(x<=t) write(sum[x][y]),putchar('
    ');
    			else{
    				int Sum=0;
    				for(int j=y;j<=n;j+=x) Sum+=a[j];
    				write(Sum),putchar('
    ');
    			}
    		}
    		else{
    			for(int j=1;j<=t;j++) sum[j][x%j]-=a[x];
    			for(int j=1;j<=t;j++) sum[j][x%j]+=y;
    			a[x]=y;
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Oracle 备份脚本
    Centos 安装DBI和ORACLE DBD
    人生到此初相见——北漂18年(10)
    备份上个月的日志
    mysql 授权
    竹杖芒鞋轻胜马,一蓑烟雨任平生——写在38岁生日
    haproxy 跨域访问:
    redis 配置说明
    vsftpd 500 OOPS: bad bool value in config file for: anon_world_readable_only
    vsftpd 配置虚拟用户
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14667469.html
Copyright © 2011-2022 走看看