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;
    }
    
  • 相关阅读:
    Python机器学习-分类
    Python2.x和Python3.x的区别
    cut命令
    uniq 命令
    sort命令
    KMP算法
    Trie树
    做10年Windows程序员与做10年Linux程序员的区别
    c语言内存模型
    C语言的一个关键字——static
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14667469.html
Copyright © 2011-2022 走看看