P3396 哈希冲突

一开始看着题目毫无思路…
只有一个暴力才能维持的了10分的样子…
想着打开时的标签:分块….
死活不会统计…
然后弃疗…
换了一个方向思考,,,
首先如果查询x>y肯定都不用管..直接输出0
考虑模数在n范围以内,那么对于模数特别大的情况,发现每个池子的数很少,可以暴力统计。
对于模数小的情况,发现他的预处理很简单的样子…
然后就发现,,,把大于sqrt(n)的数暴力处理是在O(n) 的,把小于n的数更新也是O(n)
发现这样处理时间O(nn)

c++代码如下:

#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i = x; i <= y ; ++ i)
#define repd(i,x,y) for(register int i = x; i >= y ; -- i)
using namespace std;
template<typename T>inline void read(T&x)
{
    char c;int sign = 1;x = 0;
    do { c = getchar(); if( c == '-' ) sign = -1; }while(!isdigit(c));
    do { x = x * 10 + c - '0'; c =getchar(); } while(isdigit(c));
    x *= sign;
}

const int N = 400;
int pre[N][N],a[N*N];
int n,m,d;

inline void PRE()
{
    rep(j,1,n)
        rep(i,1,d)
            pre[i][j%i] += a[j];
}

inline void solve(int x,int y)
{
    if(y >= x) return void(puts("0"));
    if(x > d)
    {
        int ans = 0,now = y;
        while(now <= n)
        {
            ans += a[now];
            now += x;
        }
        printf("%d\n",ans);
    }
    else printf("%d\n",pre[x][y]);
}

inline void update(int x,int y)
{
    rep(i,1,d)
        pre[i][x % i] += y - a[x];
    a[x] = y;
}

char op[2];
int x,y;
int main()
{
    read(n); read(m);
    d = sqrt(n);
    rep(i,1,n) read(a[i]);
    PRE();
    rep(i,1,m)
    {
        scanf("%s",op);
        if( op[0] == 'A' ) 
        {
            read(x); read(y);
            solve(x,y);
        }
        else 
        {
            read(x); read(y);
            update(x,y);
        }
    }
    return 0;
}
阅读更多

扫码向博主提问

Tgotp

QAQ
  • 擅长领域:
  • OI
去开通我的Chat快问
版权声明:orz https://blog.csdn.net/Tgotp/article/details/79971825
个人分类: Luogu
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭