zoukankan      html  css  js  c++  java
  • P2801 教主的魔法

    Aimee

    这是一道分块好题

    显然我们要分块,一开始我们要建立分块,在这里我们要统计的数据有:原序列,每个元素属于哪一个块,每一个块的左右边界,每一个块的lazy,块的总数。

    由于这个题目的要求,我们还需要建立一个复制的块来排序,进行查询。

    最后不成块元素单独成块。

    void build()
    {
        block=sqrt(n);tot=n/block;
        if(n%block) tot++;
        for(register int i=1;i<=n;i++){
            belong[i]=(i-1)/block+1;d[i]=a[i];
        }
        for(register int i=1;i<=tot;i++){
            L[i]=(i-1)*block+1,R[i]=i*block;
        }
        R[tot]=n;
        for(register int i=1;i<=tot;i++){
            sort(d+L[i],d+R[i]+1);
        }
    }
    

    修改部分:

    对于在一个块内的部分,暴力修改

    对于不在一个块内的范围,两边暴力修改,中间lazy标记一下

    void build()
    {
        block=sqrt(n);tot=n/block;
        if(n%block) tot++;
        for(register int i=1;i<=n;i++){
            belong[i]=(i-1)/block+1;d[i]=a[i];
        }
        for(register int i=1;i<=tot;i++){
            L[i]=(i-1)*block+1,R[i]=i*block;
        }
        R[tot]=n;
        for(register int i=1;i<=tot;i++){
            sort(d+L[i],d+R[i]+1);
        }
    }
    void change()
    {
        if(belong[x]==belong[y]){
            for(register int i=x;i<=y;i++){
                a[i]+=k;
            }
            for(register int i=L[belong[x]];i<=R[belong[x]];i++){
                d[i]=a[i];
            }
            sort(d+L[belong[x]],d+R[belong[x]]+1);
        }
        else{
            for(register int i=x;i<=R[belong[x]];i++){
                a[i]+=k;
            }
            for(register int i=L[belong[x]];i<=R[belong[x]];i++){
                d[i]=a[i];
            }
            sort(d+L[belong[x]],d+R[belong[x]]+1);
            for(register int i=L[belong[y]];i<=y;i++){
                a[i]+=k;
            }
            for(register int i=L[belong[y]];i<=R[belong[y]];i++){
                d[i]=a[i];
            }
            sort(d+L[belong[y]],d+R[belong[y]]+1);
            for(register int i=belong[x]+1;i<=belong[y]-1;i++){
                lazy[i]+=k;
            }
        }
    }
    

    查询:

    不成块部分暴力查询,成块部分二分查找

    void query()
    {
        ans=0;
        if(belong[x]==belong[y]){
            for(register int i=x;i<=y;i++){
                if(lazy[belong[x]]+a[i]>=k) ans++;
            }
            printf("%d
    ",ans);
            return;
        }
        else{
            for(register int i=x;i<=R[belong[x]];i++){
                if(lazy[belong[x]]+a[i]>=k) ans++;
            }
            for(register int i=L[belong[y]];i<=y;i++){
                if(lazy[belong[y]]+a[i]>=k) ans++;
            }
            for(register int i=belong[x]+1;i<=belong[y]-1;i++){
                int ll=L[i],rr=R[i],result=0,mid;
                while(ll<=rr)
                {
                    mid=(ll+rr)>>1;
                    if(d[mid]+lazy[i]>=k)
                        rr=mid-1,result=R[i]-mid+1;
                    else
                        ll=mid+1;
                }
                ans+=result;
            }
            printf("%d
    ",ans);
        }
    }
    

    完整部分

    #include<bits/stdc++.h>
    using namespace std;
    int a[1000007],d[1000007],L[1007],R[1007],belong[10000007],lazy[1007],ans;
    int n,q,block,tot,x,y,k;
    char cz;
    template <typename Tp>
    void read(Tp &x){
        x=0;char ch=1;int fh;
        while(ch!='-'&&(ch>'9'||ch<'0')){
            ch=getchar();
        }
        if(ch=='-'){
            fh=-1;ch=getchar();
        }else fh=1;
        while(ch>='0'&&ch<='9'){
            x=(x<<1)+(x<<3)+ch-'0';ch=getchar();
        }
        x*=fh;
    }
    void fr(char &x)
    {
        x=0;while(x!='M'&&x!='A') x=getchar();
    }
    void build()
    {
        block=sqrt(n);tot=n/block;
        if(n%block) tot++;
        for(register int i=1;i<=n;i++){
            belong[i]=(i-1)/block+1;d[i]=a[i];
        }
        for(register int i=1;i<=tot;i++){
            L[i]=(i-1)*block+1,R[i]=i*block;
        }
        R[tot]=n;
        for(register int i=1;i<=tot;i++){
            sort(d+L[i],d+R[i]+1);
        }
    }
    void change()
    {
        if(belong[x]==belong[y]){
            for(register int i=x;i<=y;i++){
                a[i]+=k;
            }
            for(register int i=L[belong[x]];i<=R[belong[x]];i++){
                d[i]=a[i];
            }
            sort(d+L[belong[x]],d+R[belong[x]]+1);
        }
        else{
            for(register int i=x;i<=R[belong[x]];i++){
                a[i]+=k;
            }
            for(register int i=L[belong[x]];i<=R[belong[x]];i++){
                d[i]=a[i];
            }
            sort(d+L[belong[x]],d+R[belong[x]]+1);
            for(register int i=L[belong[y]];i<=y;i++){
                a[i]+=k;
            }
            for(register int i=L[belong[y]];i<=R[belong[y]];i++){
                d[i]=a[i];
            }
            sort(d+L[belong[y]],d+R[belong[y]]+1);
            for(register int i=belong[x]+1;i<=belong[y]-1;i++){
                lazy[i]+=k;
            }
        }
    }
    void query()
    {
        ans=0;
        if(belong[x]==belong[y]){
            for(register int i=x;i<=y;i++){
                if(lazy[belong[x]]+a[i]>=k) ans++;
            }
            printf("%d
    ",ans);
            return;
        }
        else{
            for(register int i=x;i<=R[belong[x]];i++){
                if(lazy[belong[x]]+a[i]>=k) ans++;
            }
            for(register int i=L[belong[y]];i<=y;i++){
                if(lazy[belong[y]]+a[i]>=k) ans++;
            }
            for(register int i=belong[x]+1;i<=belong[y]-1;i++){
                int ll=L[i],rr=R[i],result=0,mid;
                while(ll<=rr)
                {
                    mid=(ll+rr)>>1;
                    if(d[mid]+lazy[i]>=k)
                        rr=mid-1,result=R[i]-mid+1;
                    else
                        ll=mid+1;
                }
                ans+=result;
            }
            printf("%d
    ",ans);
        }
    }
    int mian()
    {
        read(n);read(q);
        for(register int i=1;i<=n;i++)
            read(a[i]);
        build();
        while(q--){
            fr(cz);
            read(x);read(y);read(k);
            if(cz=='M'){
                change();
            }
            if(cz=='A'){
                query();
            }
        }
        return 0;
    }
    
  • 相关阅读:
    进阶新的阶段--LCD
    UART的调试
    s5pv210的定时器
    s5pv210的外部中断
    按键的轮询
    点亮指路灯
    队列里面的二级指针
    链表实现学生成绩管理系统
    链表基本功能
    new的用法
  • 原文地址:https://www.cnblogs.com/For-Miku/p/14589263.html
Copyright © 2011-2022 走看看