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;
    }
    
  • 相关阅读:
    特效优化
    Jsp
    JRebel 热部署
    mysql
    行为树
    Medium | LeetCode 139. 单词拆分 | 动态规划
    Medium | LeetCode 31. 下一个排列
    Easy | LeetCode 27. 移除元素 | 快慢指针
    Medium | LeetCode 437. 路径总和 III | 树 + 回溯 + 前缀和
    Medium | LeetCode 337. 打家劫舍 III | 树后序遍历 + 动态规划
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14667469.html
Copyright © 2011-2022 走看看