zoukankan      html  css  js  c++  java
  • BZOJ 3343 教主的魔法(分块)

    题意:

    有一个1e6的数组,t次操作:将[l,r]内的值增加w,或者查询[l,r]内的值大于等于add的

    思路:

    分块,块大小为sqrt(n),每次只需要暴力头尾两块,中间的整块打标记,

    对于查询查操作,块内排序然后二分即可

    复杂度O(T(sqrt(n)+sqrt(n)logn))

    代码:

    可以弄两个数组对应着写,会比我这样stl乱写快一倍

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
     
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
    //#define lowbit(x) ((x)&(-x)) 
     
    using namespace std;
     
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
     
    const db eps = 1e-6;
    const int mod = 1e9+7;
    const int maxn = 1e6+100;
    const int maxm = 2e6+100;
    const int inf = 0x3f3f3f3f;
     
    //const db pi = acos(-1.0);
     
    
    struct node{
        int id;
        ll v;
    };
    int n, q;
    vector<node>blc[maxn];
    int block;
    bool cmp(node a, node b){
        return a.v<b.v;
    }
    ll add[maxn];
    int main(){
        scanf("%d %d", &n, &q);
        int block = (int)sqrt(n);
        for(int i = 0; i < n; i++){
            node tmp;
            tmp.id = i;
            scanf("%lld", &tmp.v);
            blc[i/block].pb(tmp);
        }
        for(int i = 0; i <= (n-1)/block; i++){
            sort(blc[i].begin(), blc[i].end(), cmp);
        }
        while(q--){
            char op[3];
            int x, y;
            ll w;
            scanf("%s",op+1);
            scanf("%d %d %lld", &x, &y, &w);
            x--;y--;
            int bx = x/block;
            int by = y/block;
            if(op[1]=='M'){
                if(bx==by){
                    for(int i = 0; i < (int)blc[bx].size(); i++){
                        node a = blc[bx][i];
                        if(a.id>=x&&a.id<=y)blc[bx][i].v+=w;
                    }
                    sort(blc[bx].begin(), blc[bx].end(),cmp);
                }
                else{
                    int rx = min(n-1, (bx+1)*block-1);
                    int ly = by*block;
                    for(int i = 0; i < (int)blc[bx].size(); i++){
                        int id = blc[bx][i].id;
                        if(id>=x&&id<=y)blc[bx][i].v+=w;
                    }sort(blc[bx].begin(), blc[bx].end(),cmp);
                    for(int i = 0; i < (int)blc[by].size(); i++){
                        int id = blc[by][i].id;
                        if(id>=x&&id<=y)blc[by][i].v+=w;
                    }sort(blc[by].begin(), blc[by].end(),cmp);
                    for(int i = bx+1; i < by; i++){
                        add[i]+=w;
                    }
                }
            }
            else{
                int ans = 0;
                if(bx==by){
                    for(int i = 0; i < (int)blc[bx].size(); i++){
                        int id = blc[bx][i].id;
                        if(id>=x&&id<=y&&blc[bx][i].v+add[bx]>=w)ans++;
                    }
                }
                else{
                    for(int i = 0; i < (int)blc[bx].size(); i++){
                        int id = blc[bx][i].id;
                        if(id>=x&&id<=y&&blc[bx][i].v+add[bx]>=w)ans++;
                    }
                    for(int i = 0; i < (int)blc[by].size(); i++){
                        int id = blc[by][i].id;
                        if(id>=x&&id<=y&&blc[by][i].v+add[by]>=w)ans++;
                    }
                    //printf("--%d
    ",ans);
                    for(int i = bx+1; i < by; i++){
                        ll x = w-add[i];
                        int l = 0;
                        int r = block-1;
                        int pos = block;
                        while(l<=r){
                            int mid = (l+r)>>1;
                            if(blc[i][mid].v>=x){
                                pos = mid;
                                r = mid-1;
                            }
                            else l = mid+1;
                        }
                        ans+=block-pos;
                    }
                }
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
    /*
    5 3
    1 2 3 4 5
    A 1 5 4
    M 3 5 1
    A 1 5 4
    
    5 7
    3 1 4 2 5
    A 1 5 4
    M 3 5 1
    M 3 5 2
    A 1 5 4
    M 1 1 3
    A 1 5 4
    A 1 5 10
    
    5 3
    3 1 4 2 5
    A 1 5 10
    M 1 5 2
    A 1 5 10
     */
  • 相关阅读:
    React后台管理系统-商品管理列表组件
    React后台管理系统-商品列表搜索框listSearch组件
    React后台管理系统-table-list组件
    React后台管理系统-用户列表页面
    React后台管理系统- rc-pagination分页组件封装
    React后台管理系统-登录页面
    React后台管理系统-首页Home组件
    React后台管理系统-后台接口封装
    ThreadLocal的原理、作用、使用弱引用原因、应用举例
    N皇后问题的递归与非递归解法
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/11189224.html
Copyright © 2011-2022 走看看