zoukankan      html  css  js  c++  java
  • 分块

    数列分块入门训练集:


    讲解

    入门2:

    求出小于每个数的个数,维持块内有序,进行二分。

    #include <bits/stdc++.h>
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef pair<ll,int>P;
    const int N=5e4+5;
    vector<ll>v[N];
    int L[N],R[N],belong[N];
    ll d[N],lazy[N];
    int block,num;
    void read(int &x)
    {
        x=0;
        int f=1;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<3)+(x<<1)+ch-'0';
            ch=getchar();
        }
        x*=f;
    }
    void solve(int p)
    {
        v[p].clear();
        for(int i=L[p];i<=R[p];i++)
            v[p].pb(d[i]);
        sort(v[p].begin(),v[p].end());
    }
    void build(int n)
    {
        block=sqrt(n);
        num=n/block;
        if(n%block)
            num++;
        for(int i=1;i<=num;i++)
            L[i]=(i-1)*block+1,R[i]=block*i;
        R[num]=n;
        for(int i=1;i<=n;i++)
            belong[i]=(i-1)/block+1;
        memset(lazy,0,sizeof(lazy));
    }
    void update(int l,int r,int c)
    {
        int p=belong[l];
        int q=belong[r];
        if(p==q)
        {
            for(int i=l;i<=r;i++)
                d[i]+=c;
            solve(p);
        }
        else
        {
            for(int i=p+1;i<q;i++)
                lazy[i]+=c;
            for(int i=l;i<=R[p];i++)
                d[i]+=c;
            solve(p);
            for(int i=L[q];i<=r;i++)
                d[i]+=c;
            solve(q);
        }
    }
    int query(int l,int r,int c)
    {
        ll t=1LL*c*c;
        int res=0,p=belong[l],q=belong[r];
        if(p==q)
        {
            for(int i=l;i<=r;i++)
            {
                if(d[i]<t-lazy[p])
                    res++;
            }
        }
        else
        {
            for(int i=p+1;i<q;i++)
            {
                int m=lower_bound(v[i].begin(),v[i].end(),t-lazy[i])-v[i].begin();
                res+=m;
            }
            for(int i=l;i<=R[p];i++)
            {
                if(d[i]<t-lazy[p])
                    res++;
            }
            for(int i=L[q];i<=r;i++)
            {
                if(d[i]<t-lazy[q])
                    res++;
            }
        }
        return res;
    }
    int main()
    {
        int n,x;
        read(n);
        build(n);
        for(int i=1;i<=n;i++)
        {
            read(x);
            d[i]=x;
            v[belong[i]].pb(x);
        }
        for(int i=1;i<=num;i++)
            sort(v[i].begin(),v[i].end());
        int op,l,r,c;
        for(int i=1;i<=n;i++)
        {
            read(op);
            read(l);
            read(r);
            read(c);
            if(op==0)
                update(l,r,c);
            else
                printf("%d
    ",query(l,r,c));
        }
        return 0;
    }
    
    

    楼房重建 HYSBZ - 2957:

    分析:

    维护每个块的最大斜率值和块内呈递增的高度序列,每次更新时,重新维护序列。
    复杂度:(O(m*(sqrt{n}+num*log(sqrt{n}))))

    #include <bits/stdc++.h>
    #define pb push_back
    using namespace std;
    const int N=1e5+5;
    const int maxn=1005;
    double hm[maxn],h[N];
    vector<double>v[maxn];
    int block,num;
    int belong[N],L[maxn],R[maxn];
    void build(int n)
    {
        block=sqrt(n);
        num=n/block;
        if(n%block)
            num++;
        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<=n;i++)
            belong[i]=(i-1)/block+1;
    }
    void update(int x,int y)
    {
        int p=belong[x];
        v[p].clear();
        h[x]=1.0*y/x;
        double m=0;
        for(int i=L[p];i<=R[p];i++)
        {
            if(h[i]>m)
            {
                v[p].pb(h[i]);
                m=h[i];
            }
        }
        hm[p]=m;
    }
    int query()
    {
        int res=0;
        double m=0;
        for(int i=1;i<=num;i++)
        {
            int t=upper_bound(v[i].begin(),v[i].end(),m)-v[i].begin();
            res+=(v[i].size()-t);
            if(hm[i]>m)//注意
                m=hm[i];
        }
        return res;
    }
    int main()
    {
        int n,m,x,y;
        scanf("%d%d",&n,&m);
        build(n);
        while(m--)
        {
            scanf("%d%d",&x,&y);
            update(x,y);
            printf("%d
    ",query());
        }
        return 0;
    }
    
    
  • 相关阅读:
    css 分类+选择器
    emmet语法
    程序员能力矩阵
    时间管理

    java 内存 解析
    SQL 查询优化
    2016 书单计划
    ssh框架;
    Mybatis;
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/12493388.html
Copyright © 2011-2022 走看看