zoukankan      html  css  js  c++  java
  • HDU 1166

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166

    题解:

    本题作为一个模板题,我用它来检验过总查询时间复杂度为 $O(q log n)$ 的树状数组模板、线段树模板以及zkw线段树模板;而今天,我们要来用分块来写这道题目。

    时间复杂度:

    初始化 $O(n)$;每次修改均为 $O(1)$,每次查询为 $O(sqrt n)$;总时间复杂度 $O(n + q sqrt n)$。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=5e4+10;
    
    int n;
    
    int a[maxn],sum[maxn];
    int block[maxn],len,tot;
    int L[maxn],R[maxn];
    void init(int l,int r)
    {
        memset(sum,0,sizeof(sum));
        len=sqrt(r-l+1);
        tot=0;
        for(int i=l;i<=r;i++)
        {
            block[i]=(i-l)/len+1;
            tot=max(block[i],tot);
            sum[block[i]]+=a[i];
            if(i==l) L[block[i]]=i;
            if(i==r) R[block[i]]=r;
            if(l<=i-1 && i<=r && block[i-1]!=block[i])
            {
                R[block[i-1]]=i-1;
                L[block[i]]=i;
            }
        }
    }
    void add(int p,int x)
    {
        a[p]+=x;
        sum[block[p]]+=x;
    }
    int ask(int l,int r)
    {
        int st=block[l],ed=block[r];
        int res=0;
        if(st==ed) for(int i=l;i<=r;i++) res+=a[i];
        else
        {
            for(int i=l;i<=R[st];i++) res+=a[i];
            for(int i=st+1;i<=ed-1;i++) res+=sum[i];
            for(int i=L[ed];i<=r;i++) res+=a[i];
        }
        return res;
    }
    
    int main()
    {
        int T;
        cin>>T;
        for(int kase=1;kase<=T;kase++)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;i++) scanf("%d",&a[i]);
            init(1,n);
            printf("Case %d:
    ",kase);
            char op[6];
            while(scanf("%s",op))
            {
                if(op[0]=='E') break;
                if(op[0]=='Q')
                {
                    int l,r;
                    scanf("%d%d",&l,&r);
                    printf("%d
    ",ask(l,r));
                }
                else if(op[0]=='A')
                {
                    int pos,x;
                    scanf("%d%d",&pos,&x);
                    add(pos,x);
                }
                else if(op[0]=='S')
                {
                    int pos,x;
                    scanf("%d%d",&pos,&x);
                    add(pos,-x);
                }
            }
        }
    }
  • 相关阅读:
    建立十字链表
    KMP算法
    魔术师发牌问题(循环链表)
    约瑟夫问题(循环链表)
    中缀表达式 转 (逆)波兰表达式
    中缀表达式求值
    迷宫问题(回溯法)
    范数
    AUC
    概率论
  • 原文地址:https://www.cnblogs.com/dilthey/p/9746445.html
Copyright © 2011-2022 走看看