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

    题目

    众所周知,模数的hash会产生冲突。例如,如果模的数p=7,那么4和11便冲突了。

    B君对hash冲突很感兴趣。他会给出一个正整数序列value[]。

    自然,B君会把这些数据存进hash池。第value[k]会被存进(k%p)这个池。这样就能造成很多冲突。

    B君会给定许多个p和x,询问在模p时,x这个池内数的总和。

    另外,B君会随时更改value[k]。每次更改立即生效。

    保证1<=p<n1<=p<n.

    输入格式

    第一行,两个正整数n,m,其中n代表序列长度,m代表B君的操作次数。

    第一行,n个正整数,代表初始序列。

    接下来m行,首先是一个字符cmd,然后是两个整数x,y。

    若cmd='A',则询问在模x时,y池内数的总和。

    若cmd='C',则将value[x]修改为y。

    输出格式

    对于每个询问输出一个正整数,进行回答。

    输入样例

    10 5
    1 2 3 4 5 6 7 8 9 10
    A 2 1
    C 1 20
    A 3 1
    C 5 1
    A 5 0

    输出样例

    25
    41
    11

    提示

    样例解释

    A 2 1的答案是1+3+5+7+9=25.

    A 3 1的答案是20+4+7+10=41.

    A 5 0的答案是1+10=11.

    数据规模

    对于10%的数据,有n<=1000,m<=1000.

    对于60%的数据,有n<=100000.m<=100000.

    对于100%的数据,有n<=150000,m<=150000.

    保证所有数据合法,且1<=value[i]<=1000.

    题解

    越来越喜欢这样的分块算法
    我们考虑暴力:
    对于查询(p,x),从x号位开始,每次加p,统计对应位置的数
    (O(n^2))

    何破?
    开数组ans[p][x]表示模p为x的答案,查询(O(1)),而预处理与空间都是(O(n^2))

    考虑分块
    观察暴力的模式,每次加p,当p足够大时所需次数其实很少【比如(sqrt{n})
    我们就对(sqrt{n})以内的p预处理,大于(sqrt{n})的暴力
    完美解决

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long int
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
    using namespace std;
    const int maxn = 150005,maxm = 405,INF = 1000000000;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
    	while (c >= 48 && c <= 57) {out = (out << 3) + (out << 1) + c - '0'; c = getchar();}
    	return out * flag;
    }
    int Ans[maxm][maxm],n,m,val[maxn],B;
    int main(){
    	n = read(); m = read(); B = (int)sqrt(n); int x,y;
    	REP(i,n) {val[i] = read(); REP(j,B) Ans[j][i % j] += val[i];}
    	while (m--){
    		char c = getchar(); while (c != 'A' && c != 'C') c = getchar();
    		x = read(); y = read();
    		if (c == 'A'){
    			if (x <= B) printf("%d
    ",Ans[x][y]);
    			else {
    				int ans = 0;
    				if (y < x) for (int i = y; i <= n; i += x) ans += val[i];
    				printf("%d
    ",ans);
    			}
    		}else {
    			REP(j,B) Ans[j][x % j] += y - val[x];
    			val[x] = y;
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    JSON数据的中文乱码问题
    使用json-lib进行Java和JSON之间的转换
    struts2 struts.xml配置文件详解
    php位运算的应用(转)
    oracle数据库导入导出的dmp(转)
    Java多线程-工具篇-BlockingQueue(转)
    javaweb之Filter详解(转)
    MYSQL写入数据时报错ERROR 1366 (HY000): Incorrect string value: 'xE8x8BxB1xE5xAFxB8...' for c 插入中文不能插入
    插入中文错误ERROR 1406 (22001): Data too long for column 'name' at row 1
    SQL语句处理一些修改、新增、删除、修改属性操作(MySql)
  • 原文地址:https://www.cnblogs.com/Mychael/p/8330573.html
Copyright © 2011-2022 走看看