zoukankan      html  css  js  c++  java
  • 数列分块

    数列分块1

    //分块后在块内二分,两边暴力处理 
    
    #include<cstdio>
    #include<cctype>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int n,block,tot,belong[50002],r[250],a[50002],b[50002],ad[250];
    
    inline void read(int &x){
        char ch=getchar();x=0;int f=1;
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        x*=f;
    }
    
    void reset(int whic){
        for(int i=r[whic-1]+1;i<=r[whic];i++)b[i]=a[i];
        sort(b+r[whic-1]+1,b+r[whic]);
    }
    
    void add(int x,int y,int c){
        int lb=belong[x],rb=belong[y];
        if(lb==rb){
            for(register int i=x;i<=y;i++)a[i]+=c;
            reset(lb);
            return;
        }
        if(x%block!=1){
            for(register int i=x;i<=r[belong[x]];i++)a[i]+=c;
            reset(lb);
            lb++;
        }
        if(y%block>0){
            for(register int i=r[belong[y]-1]+1;i<=y;i++)a[i]+=c;
            reset(rb);
            rb--;
        }
        for(register int i=lb;i<=rb;i++)ad[i]+=c;
    }
    
    int query(int x,int y,int c){
        int lb=belong[x],rb=belong[y];
        int ans=0;
        if(lb==rb){
            for(register int i=x;i<=y;i++)if(a[i]+ad[belong[x]]<c)ans++;
            return ans;
        }
        if(x%block!=1){
            for(register int i=x;i<=r[belong[x]];i++)if(a[i]+ad[belong[x]]<c)ans++;
            lb++;
        }
        if(y%block>0){
            for(register int i=r[belong[y]-1]+1;i<=y;i++)
            if(a[i]+ad[belong[y]]<c)ans++;
            rb--;
        }
        for(int i=lb;i<=rb;i++){
        ans=ans+lower_bound(b+r[i-1]+1,b+r[i],c-ad[i])-b-r[i-1]-1;//被lower_bound处理卡了两天。。。 
        if(c-ad[i]>b[r[i]])ans++;//因为若数组最后一个数仍小于寻找的数,返回的是最后一个位置,未将最后一个数算进去 
        }return ans;
        
    }
    
    inline void putans(int x){
        if(x>=10)putans(x/10);putchar('0'+x%10);return;
    }
    
    int main(){
        read(n);block=sqrt(n);
        for(register int i=1;i<=n;i++){
            read(a[i]);
            belong[i]=tot;
            if(i%block==1){r[tot]=i-1;belong[i]=++tot;}
        }
        b[0]=a[0]=-1000000;
        r[tot]=n;
        for(int i=1;i<=tot;i++)reset(i);
        for(register int i=1;i<=n;i++){
            int opt,x,y,c;
            read(opt);read(x);read(y);read(c);
            if(opt==0)add(x,y,c);else printf("%d\n",query(x,y,c*c));
        }
    }

    数列分块2

    #include<cstdio>
    #include<algorithm>
    #include<cctype>
    #include<set>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    int n,block,tot,a[100002],belong[100002],r[350],ad[350];
    set<int>st[350];
    
    inline void read(int&x){
        char ch=getchar();x=0;int f=1;
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        x*=f;
    }
    
    void add(int x,int y,int c){
        int lb=belong[x],rb=belong[y];
        if(lb==rb){
            for(int i=x;i<=y;i++){
                st[lb].erase(a[i]);a[i]+=c;st[lb].insert(a[i]);
            }
            return;
        }
        if(x%block!=1){
            for(int i=x;i<=r[lb];i++){
                st[lb].erase(a[i]);a[i]+=c;st[lb].insert(a[i]);
            }
            lb++;
        }
        if(y%block>0){
            for(int i=r[rb-1]+1;i<=y;i++){
                st[rb].erase(a[i]);a[i]+=c;st[rb].insert(a[i]);
            }
            rb--;
        }
        for(int i=lb;i<=rb;i++)ad[i]+=c;
    }
    
    int query(int x,int y,int c){
        int ans=-1,lb=belong[x],rb=belong[y];
        if(lb==rb){
            for(int i=x;i<=y;i++)if(a[i]+ad[lb]<c)ans=max(ans,a[i]+ad[lb]);
            return ans;
        }
        if(x%block!=1){
            for(int i=x;i<=r[lb];i++)if(a[i]+ad[lb]<c)ans=max(ans,a[i]+ad[lb]);
            lb++;
        }
        if(y%block>0){
            for(int i=r[rb-1]+1;i<=y;i++)if(a[i]+ad[rb]<c)ans=max(ans,a[i]+ad[rb]);
            rb--;
        }
        for(int i=lb;i<=rb;i++){
            set<int>::iterator it=st[i].lower_bound(c-ad[i]);
            if(it!=st[i].begin()){
                it--;
                ans=max(ans,*it+ad[i]);
            }
        }
        return ans;
    }
    
    int main(){
        read(n);block=sqrt(n);
        for(int i=1;i<=n;i++){
            read(a[i]);
            if(i%block==1)r[tot]=tot*block,belong[i]=++tot;else belong[i]=tot;
            st[belong[i]].insert(a[i]);
        }
        r[tot]=n;
        for(int i=1;i<=n;i++){
            int opt,x,y,c;
            read(opt);read(x);read(y);read(c);
            if(opt==0)add(x,y,c);else printf("%d\n",query(x,y,c));
        }
    }

    数列分块3

    #include<cstdio>
    #include<cctype>
    #include<cmath>
    using namespace std;
    int n,block,tot;
    long long a[50002],belong[50002],r[250],ad[250];
    long long sum[250];
    
    inline void read(int &x){
        char ch=getchar();x=0;int f=1;
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        x*=f;
    }
    
    inline void read(long long &x){
        char ch=getchar();x=0;int f=1;
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        x*=f;
    }
    
    inline void add(int x,int y,int c){
        int lb=belong[x],rb=belong[y];
        if(lb==rb){
            for(int i=x;i<=y;i++)a[i]+=c;
            sum[lb]=sum[lb]+(y-x+1)*c;
            return;
        }
        if(x%block!=1){
            for(int i=x;i<=r[lb];i++)a[i]+=c;
            sum[lb]=sum[lb]+(r[lb]-x+1)*c;
            lb++;
        }
        if(y%block>0){
            for(int i=r[rb-1]+1;i<=y;i++)a[i]+=c;
            sum[rb]=sum[rb]+(y-r[rb-1])*c;
            rb--;
        }
        for(int i=lb;i<=rb;i++)ad[i]+=c;
    }
    
    inline int query(int x,int y,int c){
        long long ans=0;
        int lb=belong[x],rb=belong[y];
        if(lb==rb){
            ans=(y-x+1)*ad[lb]%(c+1);
            for(int i=x;i<=y;i++)ans=(ans+a[i])%(c+1);
            return ans;
        }
        if(x%block!=1){
            for(int i=x;i<=r[lb];i++)ans=(ans+a[i])%(c+1);
            ans=(ans+(r[lb]-x+1)*ad[lb]%(c+1))%(c+1);
            lb++;
        }
        if(y%block>0){
            for(int i=r[rb-1]+1;i<=y;i++)ans=(ans+a[i])%(c+1);
            ans=(ans+(y-r[rb-1])*ad[rb]%(c+1))%(c+1);
            rb--;
        }
        for(int i=lb;i<=rb;i++)ans=(ans+sum[i]+ad[i]*(r[i]-r[i-1])%(c+1))%(c+1);
        return ans;
    }
    
    int main(){
        read(n);block=sqrt(n);
        for(int i=1;i<=n;i++){
            read(a[i]);
            if(i%block==1){r[tot]=i-1;belong[i]=++tot;}else belong[i]=tot;
            sum[belong[i]]+=a[i];
        }
        for(int i=1;i<=n;i++){
            int opt,x,y,c;
            read(opt);read(x);read(y);read(c);
            if(opt==0)add(x,y,c);else printf("%d\n",query(x,y,c));
        }
    }
  • 相关阅读:
    使用JDBC连接MySql时出现:The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration
    Mysql Lost connection to MySQL server at ‘reading initial communication packet', system error: 0
    mysql-基本命令
    C# 监听值的变化
    DataGrid样式
    C# 获取当前日期时间
    C# 中生成随机数
    递归和迭代
    PHP 时间转几分几秒
    PHP 根据整数ID,生成唯一字符串
  • 原文地址:https://www.cnblogs.com/MikuKnight/p/8998520.html
Copyright © 2011-2022 走看看