zoukankan      html  css  js  c++  java
  • Codeforces 1207F:Remainder Problem

    You are given an array a consisting of 500000 integers (numbered from 1 to 500000). Initially all elements of a are zero.
    
    You have to process two types of queries to this array:
    
    1 x y — increase ax by y;
    2 x y — compute ∑i∈R(x,y)ai, where R(x,y) is the set of all integers from 1 to 500000 which have remainder y modulo x.
    Can you process all the queries?

    卡住自己两次的一道题,在我看来是个偏trick甚至有些套路的题,

    由于查询和的下标不是连续的,而是每隔一个固定的单位,想不到什么太好的高级数据结构去维护,这个时候可以考虑分块。

    普通的分块一般是大块维护,小块暴力,有意思的是这里恰好相反,我们注意到当x越大的时候,我们暴力做第二种操作的次数就会变少,第二种操作的复杂度是O(N/X)的,

    而当x较小的时候,我们就不能暴力去跑第二种操作,而要通过之前维护的一些信息去快速出答案,

    我们建立一个二维数组sum[x][y]表示当所有下标模x余y的数的和,也就是第二个操作询问的答案,考虑第一个操作会对哪些值产生变化,

    假设第一个操作的下标是pos,增加的量是delta,那么会对sum[1][pos%1],sum[2][pos%2],sum[3][pos%3]……产生增加delta的变化

    假设我们二维数组开成sum[MAXK][MAXK]的,那么第二种操作就是O(MAXK)的,而第二种操作在x>=MAXK的时候才需要进行,复杂度是O(N/MAXK),因此根据均值不等式,我们取MAXK=sqrt(MAXN),这样的话每次操作的复杂度就变成O(sqrt(MAXN))了,然后就做完了。

    算是分块思想的一种应用吧,如果没有什么思路的时候可以尝试去考虑一下,根据根号分块,观察是不是可以存着一侧暴力一侧维护的情况,如果可以的话就可以用分块来尝试了。

    银川的那道金牌题(放在一般区域赛最多是银牌题)也是分块,不过那个数学上应该比较容易看出来

    底下的代码里sum[][]的两维跟上面说的调换了过来。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=5e5;
    const int k=750;
    ll sum[k+5][k+5];
    int a[maxn+5];
    int q,op,x,y;
    int main()
    {
        scanf("%d",&q);
        while (q--) {
            scanf("%d%d%d",&op,&x,&y);
            if (op==1) {
                a[x]+=y;
                for (int i=1;i<k;i++)
                    sum[x%i][i]+=y;
            }
            else {
                if (x>=k) {
                    ll ans=0;
                    for (int i=y;i<=maxn;i+=x) ans+=a[i];
                    printf("%I64d
    ",ans);
                }
                else printf("%I64d
    ",sum[y][x]);
            }
        }
        return 0;
    }
  • 相关阅读:
    css3多列
    伪元素
    text文本样式二
    透明登录框
    透明度设置opacity
    超链接
    meta标签
    奇偶选择器
    OC跟Swift混编
    Swift中as as! as?的区别
  • 原文地址:https://www.cnblogs.com/xyw5vplus1/p/12247597.html
Copyright © 2011-2022 走看看