[luogu3396]哈希冲突(根号乱搞)

题目:

我是超链接

题解:

一道很奇怪的题目,我直接复制题解了。
首先,题目要我们求的东西,就是下面的代码:

for(i=k;i<=n;i+=p) ans+=value[i];

即:从 k开始,每隔p个数取一个数,求它们的和。这个算法的复杂度是O(n^2) 的。

令答案为ans[p][k],表示模数是p,余数是k。

那么,对于第i个数,如何处理它对ans的贡献呢?

for(p=1;p<=n;p++) //枚举模数
    ans[p][i%p]+=value[i]; //处理对应的贡献

看起来不错,但还是n^2啊
所以我们只处理 [1,n] [ 1 , n ] 以内的p
于是预处理的复杂度降到了 O(nn) O ( n n )
接着考虑询问。如果询问的p < size ,那显然可以O(1)给出回答。

如果p超过size,我们就暴力统计并回答。因为 p>n p > n ,所以少于 n n
个数对答案有贡献。
接着考虑修改。显然我们把p

代码:

#include <cstdio>
#include <cmath>
using namespace std;
int a[150005],ans[390][150005];
//ans[i][j]模数为i时余数为j的贡献 
int main()
{
    int n,m,x,y,i,j;
    scanf("%d%d",&n,&m);int si=sqrt(n);
    for (i=1;i<=n;i++) scanf("%d",&a[i]);
    for (i=1;i<=n;i++)
      for (j=1;j<=si;j++) ans[j][i%j]+=a[i]; 
    for (i=1;i<=m;i++)
    {
        char st=getchar();while (st!='A' && st!='C') st=getchar();
        scanf("%d%d",&x,&y);
        if (st=='A') 
        {
            if (x<=si) printf("%d\n",ans[x][y]);
            else 
            {
            int ans=0;
            for (j=y;j<=n;j+=x) ans+=a[j];
            printf("%d\n",ans); 
            }
        }else
        {
            for (j=1;j<=si;j++) ans[j][x%j]=ans[j][x%j]-a[x]+y;
            a[x]=y;
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值