zoukankan      html  css  js  c++  java
  • 解题:洛谷3396 哈希冲突

    题面

    题外话:现在还不知道退不退役啊QAQ,因为发挥太渣,把Day1T3和Day2T1这仅有的两道有区分度的题全写挂了(没区分度的其他题**倒挺稳。。。),退不退役全看数据湿度了(400-460,教练建议的线是420,orz i207M 530+)

    在可能是苟在机房的最后一周里打算学学分块和莫队=。=

    分块不只是一种处理序列问题的方法,更多的是一种均摊复杂度的思想(比如这个题)

    (我好像在汇总里写过这个思想)

    我们现在有两种暴力:第一种暴力是$O(mod)$的,即先$O(n*mod)$处理在模某数意义下每个池子里的数,然后每次$O(1)$查表+$O(mod)$修改,问题是模数很大时会GG;第二种暴力是$O(frac{n}{mod})$,直接在序列上每隔$mod$统计,然后$O(1)$修改一下序列。然后你把这两种暴力揉在一起,对于$mod<=sqrt(n)$的情况采用暴力1,对于$mod>sqrt(n)$的情况采用暴力2,于是得到了一个$O((n+m)sqrt(n))$的算法

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int N=150005,Sqrt=390;
     6 long long a[N],bkt[Sqrt+5][Sqrt+5];
     7 int n,m,t1,t2; char rd[5];
     8 int main ()
     9 {
    10     scanf("%d%d",&n,&m);
    11     for(int i=1;i<=n;i++)
    12     {
    13         scanf("%lld",&a[i]);
    14         for(int j=1;j<=Sqrt;j++)
    15             bkt[j][i%j]+=a[i];
    16     }
    17     while(m--)
    18     {
    19         scanf("%s%d%d",rd,&t1,&t2);
    20         if(rd[0]=='A')
    21         {
    22             if(t1<=Sqrt)
    23                 printf("%lld
    ",bkt[t1][t2%t1]);
    24             else 
    25             {
    26                 long long ans=0;
    27                 for(int i=t2;i<=n;i+=t1)
    28                     ans+=a[i];
    29                 printf("%lld
    ",ans);
    30             }
    31         }
    32         else 
    33         {
    34             for(int i=1;i<=Sqrt;i++)
    35                 bkt[i][t1%i]+=t2-a[t1];
    36             a[t1]=t2;
    37         }
    38     }
    39     return 0;
    40 }
    View Code
  • 相关阅读:
    1011. A+B和C (15)
    1010. 一元多项式求导 (25)
    1009. 说反话 (20)
    1007. 素数对猜想 (20)
    1008. 数组元素循环右移问题 (20)
    1006. 换个格式输出整数 (15)
    1005. 继续(3n+1)猜想 (25)
    算法学习(八)
    算法学习(七)
    算法学习(六)
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/9954688.html
Copyright © 2011-2022 走看看