首页 > 其他 > 详细

洛谷 P3396 哈希冲突

时间:2018-08-15 22:31:39      阅读:196      评论:0      收藏:0      [点我收藏+]

题意:给你一些数,有两种操作,一种是给你一个模数x和余数y,问你在模数x的条件下,余数为y的数的总和为多少,另一种操作是修改一个位置的数值

思路:看了题解,没想到是对模数分块,小规模打表,大规模暴力,这种操作我也是第一次见,我们直接把sqrt n之内的数直接暴力求一遍,这样的复杂度是nsqrt n的

然后sqrt修改,小于sqrt n就是O1查询,大于的部分其实不超过sqrt n块,所以就sqrt n查询

代码;

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
inline LL read()
{
    LL x=0,f=1;char ch=getchar();
    while(ch>9||ch<0){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
    return x*f;
}
const int maxn=150007;
int n,m;
int a[maxn];
LL f[1001][1001];
int block;
int main()
{
    n=read(),m=read();block=min((int)sqrt(n),1001);
    for(int i=1;i<=n;i++)a[i]=read();
    for(int i=1;i<=block;i++){
        for(int j=1;j<=n;j++){
            f[i][j%i]+=a[j];
        }
    }
//    for(int i=1;i<=n;i++){
//        for(int j=1;j<=block;j++){
//            f[j][i%j]+=a[i];
//        }
//    }
    while(m--){
        char op[5];
        scanf("%s",op);
        if(op[0]==A){
            int x=read(),y=read();
            if(x<=block){
                printf("%lld\n",f[x][y]);
            }
            else{
                LL sum=0;
                y%=x;
                if(y==0)y=x;
//                printf("test %d %d %d\n",x,y,a[5]+a[10]);
                for(int i=y;i<=n;i+=x){
                    sum+=a[i];
                }
                printf("%lld\n",sum);
            }
        }
        else{
            int x=read(),y=read();
            LL val=y-a[x];
            for(int i=1;i<=block;i++){
                f[i][x%i]+=val;
            }
            a[x]=y;
        }
    }
    return 0;
}

 

洛谷 P3396 哈希冲突

原文:https://www.cnblogs.com/lalalatianlalu/p/9484240.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!