zoukankan      html  css  js  c++  java
  • 分块见习

    分块初始化:

    int a[50005];//原始序列
    int l[2000];//第i个块的左区间端点
    int r[2000];//第i个块的右区间端点
    int pos[50005];//第i个点属于第几个块
     
    int n;
    scanf("%d",&n);
    int dis=sqrt(n);//每一块的大小
    int num=ceil(n*1.0/dis);//分块数目
    for(int i=1;i<=num;i++)
    {
        l[i]=(i-1)*dis+1;//第i个块的左区间端点
        r[i]=i*dis;//第i个块的右区间端点
    }
    r[num]=n;//最后一个块的右端点最大等于n
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        pos[i]=(i-1)/dis+1;//第i个数属于第几个块
    }
    View Code

    题:https://loj.ac/problem/6278

    题意:支持区间加,求区间小于c*c的个数

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define pb push_back
    const int inf=0x3f3f3f3f;
    const ll INF=1e18;
    const int M=5e4+4;
    int a[M],b[M],pos[M],l[M],r[M],lz[M];
    void init(int n){
        int dis=sqrt(n);
        int num=ceil(n*1.0/dis);
        for(int i=1;i<=num;i++){
            l[i]=(i-1)*dis+1;
            r[i]=i*dis;
        }
        r[num]=n;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            pos[i]=(i-1)/dis+1;
            b[i]=a[i];
        }
        for(int i=1;i<=num;i++)
            sort(b+l[i],b+r[i]+1);
    }
    void add(int L,int R,int v){
        int posl=pos[L],posr=pos[R];
        if(posl==posr){
            for(int i=L;i<=R;i++)
                a[i]+=v;
            for(int i=l[posl];i<=r[posl];i++)
                b[i]=a[i];
            sort(b+l[posl],b+r[posl]+1);
        }
        else{
            ///left
            for(int i=L;i<=r[posl];i++)
                a[i]+=v;
            for(int i=l[posl];i<=r[posl];i++)
                b[i]=a[i];
            sort(b+l[posl],b+r[posl]+1);
            ///mid
            for(int i=posl+1;i<posr;i++)
                lz[i]+=v;
            ///right
            for(int i=l[posr];i<=R;i++)
                a[i]+=v;
            for(int i=l[posr];i<=r[posr];i++)
                b[i]=a[i];
            sort(b+l[posr],b+r[posr]+1);
        }
    }
    int query(int L,int R,int c){
        int posl=pos[L],posr=pos[R];
        int cnt=0;
        if(posl==posr){
            for(int i=L;i<=R;i++)
                if(a[i]<c-lz[posl])
                    cnt++;
            return cnt;
        }
        ///left
        for(int i=L;i<=r[posl];i++)
            if(a[i]<c-lz[posl])
                cnt++;
        ///right
        for(int i=l[posr];i<=R;i++)
            if(a[i]<c-lz[posr])
                cnt++;
        ///mid
        for(int i=posl+1;i<posr;i++)
            cnt+=lower_bound(b+l[i],b+r[i]+1,c-lz[i])-(b+l[i]);
        return cnt;
    }
    int main(){
        int n;
        scanf("%d",&n);
        init(n);
    
        for(int i=1;i<=n;i++){
            int op,x,y,c;
            scanf("%d%d%d%d",&op,&x,&y,&c);
            if(op==0)
                add(x,y,c);
            else
                printf("%d
    ",query(x,y,c*c));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    fiddler应用之Composer(发送接口请求)
    fiddler应用之AutoResponder(fiddler的重定向页面功能)
    fiddler应用之设置断点(fiddler篡改request和response数据)
    fiddler应用之过滤器(用fiddler筛选特定网络请求)
    fiddler配置之对移动设备进行抓包证书安装
    fiddler配置之设置手机代理
    外部排序的基本概念
    80天考研核心短语
    地址访问冲突问题(四体交叉存取)
    制约函数法
  • 原文地址:https://www.cnblogs.com/starve/p/12830063.html
Copyright © 2011-2022 走看看