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;
    }
    
  • 相关阅读:
    基于微服务架构的RBAC权限管理系统
    用C#实现基于(OpenId Connect)的单点登录与RBAC权限验证(SSO,OIDC,RBAC)
    量化分析基础
    Ocelot 发现服务总是失败的解决办法
    windows 下安装 theano 及配置 gpu
    python scrapy 爬虫 初学
    layer弹出层框架alert与msg详解
    Workerman-文件监控-牛刀小试
    ECharts 初体验
    实验楼 linux 学习
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998102.html
Copyright © 2011-2022 走看看