zoukankan      html  css  js  c++  java
  • 【Luogu】P2801教主的魔法(分块)

      题目链接

      激动qwq。这是我A的第一道分块。

      分块之后对块内元素暴力sort。修改的时候对于整块打个标记,查询的时候只需要查C-tag就行了

      对于非整块,暴力修改,改完之后sort

      对于查询……非整块暴力查询,整块二分C-tag的位置就好啦

      

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<cmath>
    #define maxn 1000010
    #define sqtn 1200
    using namespace std;
    
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    struct Node{
        int dat,id;
        bool operator <(const Node a)const{
            return dat<a.dat;
        }
    };
    
    struct Block{
        Node q[sqtn];
        int tag,tot;
        Block(){memset(q,0,sizeof(q));    tag=tot=0;    }
    }que[sqtn];
    int d[maxn];
    int s[maxn];
    int w[maxn];
    int le[sqtn],ri[sqtn];
    
    void sorten(int x){
        Block &o=que[x];
        sort(o.q+1,o.q+o.tot+1);
        for(int i=1;i<=o.tot;++i){
            w[o.q[i].id]=i;
        }
    }
    
    int main(){
        int n=read(),m=read();
        int sqt=sqrt(n),blo=0;
        for(int i=1;i<=n;++i){
            d[i]=read();
            s[i]=(i-1)/sqt+1;
            if(s[i]>blo)    blo=s[i];
            ri[s[i]]=i;
        }
        for(int i=n;i>=1;--i){
            le[s[i]]=i;
            que[s[i]].q[++que[s[i]].tot]=(Node){d[i],i};
        }
        for(int i=1;i<=blo;++i)    sorten(i);
        for(int i=1;i<=m;++i){
            char c[10];int x,y,z;
            scanf("%s%d%d%d",c,&x,&y,&z);
            if(c[0]=='M'){
                int to=min(ri[s[x]],y);
                for(int j=x;j<=to;++j)    que[s[x]].q[w[j]].dat+=z;
                sorten(s[x]);
                if(s[x]==s[y])    continue;
                int from=max(le[s[y]],x);
                for(int j=from;j<=y;++j)    que[s[y]].q[w[j]].dat+=z;
                sorten(s[y]);
                for(int j=s[x]+1;j<s[y];++j)    que[j].tag+=z;
            }
            else if(c[0]=='A'){
                int to=min(ri[s[x]],y),ans=0;
                for(int j=x;j<=to;++j)
                    if(que[s[x]].q[w[j]].dat>=z)    ans++; 
                if(s[x]==s[y]){
                    printf("%d
    ",ans);
                    continue;
                }
                int from=max(le[s[y]],x);
                for(int j=from;j<=y;++j){
                    //printf("%d
    ",que[s[y]].q[w[j]].dat);
                    if(que[s[y]].q[w[j]].dat>=z)    ans++;
                }
                for(int j=s[x]+1;j<s[y];++j){
                    Block now=que[j];
                    int l=1,r=now.tot,lim=r+1;
                    while(l<=r){
                        int mid=(l+r)>>1;
                        if(now.q[mid].dat>=z-now.tag){
                            lim=mid;
                            r=mid-1;
                        }
                        else    l=mid+1;
                    }
                    ans+=now.tot-lim+1;
                }
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
    /*
    5 3
    1 2 3 4 5
    A 1 5 4
    M 3 5 1
    A 1 5 4
    */
  • 相关阅读:
    栈的使用
    学习
    JS中常用的工具类
    AOP的相关概念
    Git-用git同步代码
    权限管理3-整合Spring Security
    权限管理2-开发权限管理接口
    权限管理1-需求描述
    使用Canal作为mysql的数据同步工具
    使用存储过程在mysql中批量插入数据
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/8320038.html
Copyright © 2011-2022 走看看