zoukankan      html  css  js  c++  java
  • 【洛谷P3396】哈希冲突【分块】

    题目大意:

    题目链接:https://www.luogu.org/problemnew/show/P3396
    给出一个数列,其中第ii个数在mod pmod p下会被装进第i mod pi mod p个哈希池。维护一下两种操作:

    • A p xA p x:询问在mod pmod p下池xx内的数字之和
    • C x yC x y:将第xx个数字改成yy

    思路:

    根号算法好题。
    应该不算分块吧。。。
    对于这道题,我们分开两段维护:

    1. 模数Tleq T。此时我们预处理出cnt[p][x]cnt[p][x]表示在模pp下池xx的元素之和。每次询问O(1)O(1),预处理O(T)O(T)
    2. 模数>T>T。此时我们只要从xx开始,暴力求答案,每次x+=px+=p。这样的话要找nTfrac{n}{T}个答案,时间复杂度O(nT)O(frac{n}{T})

    为了均摊时间复杂度,我们令T=nTT=frac{n}{T}。显然T=nT=sqrt{n}时时间复杂度较为平均。
    总时间复杂度O(nlogn)O(nlog n)


    代码:

    #include <cmath>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int N=150010,M=410;
    int n,m,T,x,y,a[N],cnt[M][M];
    char ch;
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	T=sqrt(n);
    	if (T*T<n) T++;
    	for (int i=1;i<=n;i++)
    	{
    		scanf("%d",&a[i]);
    		for (int j=1;j<=T;j++)
    			cnt[j][i%j]+=a[i];
    	}
    	while (m--)
    	{
    		while (ch=getchar()) if (ch=='A'||ch=='C') break;
    		if (ch=='A')
    		{
    			scanf("%d%d",&x,&y);
    			if (x<=T) printf("%d
    ",cnt[x][y]);
    			else
    			{
    				int ans=0;
    				for (int i=y;i<N;i+=x)
    					ans+=a[i];
    				printf("%d
    ",ans);
    			}
    		}
    		else
    		{
    			scanf("%d%d",&x,&y);
    			for (int j=1;j<=T;j++)
    				cnt[j][x%j]-=a[x];
    			a[x]=y;
    			for (int j=1;j<=T;j++)
    				cnt[j][x%j]+=a[x];
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Asp.net MVC3 Routing study
    Sharepoint 站点页面错误问题
    vc2010 学习笔记1
    UML类成员的困惑
    河道二维水流模拟高精度算法研究
    朱庆:真三维GIS技术进展
    map
    SIGGRAPH 2010: 一场视觉盛宴[转]
    新网站开张,欢迎大家
    获取其它进程内EDIT BOX内容的一种方法
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998102.html
Copyright © 2011-2022 走看看