• P2801 教主的魔法(分块入门)


    两个月之前听yyr学长讲的分块,感觉是个很神奇的暴力,但到现在还是懵的一匹

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e6+7;
    int belong[maxn];
    int a[maxn];
    int b[maxn];
    int d[maxn];
    int l[maxn];
    int r[maxn];
    int p[maxn]; 
    int n,q;
    int num,block;
    void build()//预处理块
    {
        block=sqrt(n);
        num=n/block;
        if(n%block)
        {
            num++;
        }
        for(int i=1;i<=n;i++)
        {
            belong[i]=(i-1)/block+1;
            b[i]=a[i];
        }
        for(int i=1;i<=num;i++)
        {
            l[i]=(i-1)*block+1;
            r[i]=i*block;
        }
        r[num]=n;
        for(int i=1;i<=num;i++)
        {
            sort(b+l[i],b+r[i]+1);
        }
    }
    void update(int ll,int rr,int w)
    {
        if(belong[ll]==belong[rr])
        {
            for(int i=ll;i<=rr;i++)
            {
                a[i]+=w;
            }
            for(int i=l[belong[ll]];i<=r[belong[ll]];i++)
            {
                b[i]=a[i];
            }
            sort(b+l[belong[ll]],b+r[belong[ll]]+1);
        }
        else
        {
            for(int i=ll;i<=r[belong[ll]];i++)
            {
                a[i]+=w;
            } 
            for(int i=l[belong[ll]];i<=r[belong[ll]];i++)
            {
                b[i]=a[i];
            }
            sort(b+l[belong[ll]],b+r[belong[ll]]+1);
            for(int i=l[belong[rr]];i<=rr;i++)
            {
                a[i]+=w;
            }
            for(int i=l[belong[rr]];i<=r[belong[rr]];i++)
            {
                b[i]=a[i];
            }
            sort(b+l[belong[rr]],b+r[belong[rr]]+1);
            for(int i=belong[ll]+1;i<=belong[rr]-1;i++)
            {
                p[i]+=w;
            }
        }
    }
    int ask(int ll,int rr,int c)
    {
        int ans=0;
        if(belong[ll]==belong[rr])
        {
            for(int i=ll;i<=rr;i++)
            {
                if(a[i]+p[belong[i]]>=c)
                {
                    ans++;
                }
            }
            printf("%d
    ",ans);
        }
        else
        {
            for(int i=ll;i<=r[belong[ll]];i++)
            {
                if(a[i]+p[belong[i]]>=c)
                {
                    ans++;
                }
            }
            for(int i=l[belong[rr]];i<=rr;i++)
            {
                if(a[i]+p[belong[i]]>=c)
                {
                    ans++;
                }
            } 
            for(int i=belong[ll]+1;i<belong[rr];i++)
            {
                int l1=l[i],r1=r[i],result=0,mid;
                while(l1<=r1)
                {
                    mid=(l1+r1)>>1;
                    if(b[mid]+p[i]>=c)
                    {
                        r1=mid-1;
                        result=r[i]-mid+1;
                    }
                    else
                    {
                        l1=mid+1;
                    }
                }
                ans+=result;
            }
            printf("%d
    ",ans);
        }
    }
    int main()
    {
        int A,B,C;
        char ch[5];
        scanf("%d%d",&n,&q);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        } 
        build();
        while(q--)
        {
            scanf("%s",ch);
            scanf("%d%d%d",&A,&B,&C);
            if(ch[0]=='A')
            {
                ask(A,B,C);
            }
            else
            {
                update(A,B,C);
            }
        }
        return 0;
    } 
  • 相关阅读:
    背包九讲——动态规划
    Collection、Map、数组 遍历方式
    TCP三次握手与四次挥手
    数据结构——B树、B+树
    数据结构——红黑树
    数据结构——二叉查找树、AVL树
    jquery 抽奖示例
    comebotree树
    初玩Linux部署项目
    springMvc + websocket 实现点对点 聊天通信功能
  • 原文地址:https://www.cnblogs.com/LJB666/p/10779131.html
Copyright © 2020-2023  润新知