zoukankan      html  css  js  c++  java
  • 洛谷P3396哈希冲突

    传送门啦

    非常神奇的分块大法。

    这个题一看数据范围,觉得不小,但是如果我们以 $ sqrt(x) $ 为界限,数据范围就降到了 $ x < 400 $

    我们设数组 $ f[i][j] $ 表示在 % $ i $ 意义下余数是 $ j $ 的数的总和。

    然后我们以 $ sqrt(n) $ 为界限,小于 $ sqrt(n) $ 的直接调用数组,剩下的暴力查找。修改的话看代码吧,真的不难。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath> 
    using namespace std;
    const int maxn = 150005;
    
    inline int read(){
    	char ch = getchar();
    	int f = 1 ,x = 0;
    	while(ch > '9' || ch < '0'){if(ch == '-')f = -1; ch = getchar();}
    	while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + ch - '0';ch = getchar();}
    	return x * f;
    }
    
    int n,m,a[maxn],x,y;
    char flag;
    long long f[390][390];//表示在 %i 意义下 余数是 j 的数的总和 
    
    int main(){
    	n = read(); m = read();
    	for(int i=1;i<=n;i++){
    		a[i] = read();
    		for(int j=1;j<=sqrt(n);j++)
    			f[j][i % j] += a[i];
    	}
    	while(m--){
    		cin >> flag;
    		x = read(); y = read();
    		if(flag == 'A'){
    			if(x * x <= n)
    				printf("%lld
    ",f[x][y]);
    			else {
    				int sum = 0;
    				for(int j=y;j<=n;j+=x)
    					sum += a[j];
    				printf("%d
    ",sum);
    			}
    		}
    		else {
    			for(int j=1;j<=sqrt(n);j++)
    				f[j][x % j] += y - a[x];
    			a[x] = y;
    		}
    	}
    	return 0;
    }
    顺风不浪,逆风不怂。
  • 相关阅读:
    day22 os模块
    开始 Dojo 开发
    Java 多线程编程
    Oracle 中常用数据字典大总结
    使用Java API的5个技巧
    Java 守护线程概述
    给Java新手的一些建议——Java知识点归纳(Java基础部分)
    消息中间件收录集
    2017年Java面试题整理
    Java 9 新特性快速预览
  • 原文地址:https://www.cnblogs.com/Stephen-F/p/9883228.html
Copyright © 2011-2022 走看看