• Helter Skelter (扫描线 + 离散化 + 树状数组)


    扫描线:按照其中一个区间的标记为pos,然后左区间标记d为正影响,有区间标记d为负影响,然后根据所有的pos排序。pos从小扫到大,那么对于某一个区间一定会被扫过2次,那么经过2次之后就只剩下中间那一段的影响了,但是先提前扫过去的话后面的区间就会影响到前面的区间,反过来却不会。所以求答案的时候也是按照查询区间的左部那么我只需要一边录入数据,一边求就可以了。

    然后对于1的区间只需要用一个线段树/树状数组就可以将判断是否符合了,还有就是树状数组离散化之后对速度有些许帮助。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxm = 1e6 + 7;
    int in[maxm], discre[maxm << 1], tr[maxm << 1];
    int l, r, L, R, opL, disL;
    char ans[maxm];
    
    void TreeAdd(int rt, int num){
        while(rt <= disL){
            tr[rt] += num;
            rt = rt + (rt & -rt);
        }
    }
    
    int TreeSum(int rt){
        int ret = 0;
        while(rt){
            ret += tr[rt];
            rt = rt - (rt & -rt);
        }
        return ret;
    }
    
    struct OP{
        int pos, d, L, R;
        bool operator < (const OP& a)const{
            return pos < a.pos;
        }
    }op[maxm << 1];
    
    struct QUERY{
        int a, b, id;
        bool operator < (const QUERY& A)const{
            return a < A.a;
        }
    }query[maxm];
    
    void join(){
        op[opL].d = 1;op[opL].pos = l;
        op[opL].L = L;op[opL ++].R = R;
        op[opL].d = -1;op[opL].pos = r + 1;
        op[opL].L = L;op[opL ++].R = R;
        discre[disL ++] = L;
        discre[disL ++] = R;
    }
    
    int main(){
        int T, n, m, k;scanf("%d", &T);
        while(T --){
            k = disL = opL = 0;
            scanf("%d%d",&n, &m);
            for(int i = 1; i <= n; i ++)
                scanf("%d",&in[i]);
            for(int i = 0; i < m; i ++){
                scanf("%d%d",&query[i].a, &query[i].b), query[i].id = i;
                discre[disL ++] = query[i].b;
            }
            sort(query, query + m);
            for(int i = 1; i <= n; i ++){
                ///单区间
                if(i & 1){l = 0, r = in[i], L = R = 0; join();}
                else {l = r = 0, L = 0, R = in[i]; join();}
                ///双区间
                if(i & 1 && i < n){l = L = 0; r = in[i]; R = in[i + 1]; join();}
                else if(i < n) {l = L = 0; r = in[i + 1]; R = in[i]; join();}
                ///多区间
                l = r = L = R = 0;
                for(int j = i + 1; j < n; j ++){
                    l += ((j & 1) ? in[j] : 0);
                    L += ((j & 1) ? 0 : in[j]);
                    r = l + ((i & 1) ? in[i] : 0) + ((j & 1) ? 0 : in[j + 1]);
                    R = L + ((i & 1) ? 0 : in[i]) + ((j & 1) ? in[j + 1] : 0);
                    join();
                }
            }
            sort(op, op + opL);
            sort(discre, discre + disL);
            disL = unique(discre, discre + disL) - discre;
            for(int i = 0; i <= disL; i ++) tr[i] = 0;
            for(int i = 0; i < m; i ++){
                for(;k < opL && query[i].a >= op[k].pos; k ++){
                    int ll = lower_bound(discre, discre + disL, op[k].L) - discre + 1;
                    int rr = lower_bound(discre, discre + disL, op[k].R) - discre + 1;
                    TreeAdd(ll, op[k].d);   TreeAdd(rr + 1, -1 * op[k].d);
                }
                int qq = lower_bound(discre, discre + disL, query[i].b) - discre + 1;
                ans[query[i].id] = '0' + (TreeSum(qq) > 0);
            }
            ans[m] = 0;
            printf("%s
    ",ans);
        }
        return 0;
    }
    more crazy more get!
  • 相关阅读:
    下载文档时Safari浏览器下载后出现".html"问题
    实体框架(Entity Frmaework)简介
    系统内置委托:Func/Action
    lambda表达式不使用委托(delegate) 用FUNC
    lambda表达式
    C#生成缩略图 (通用模式)
    从底层角度看ASP.NET-A low-level Look at the ASP.NET...
    网站前端优化
    HTTP协议
    什么是AJAX? AJAX:”Asynchronous JavaScript and XML”中文意思:异步JavaScript和XML。
  • 原文地址:https://www.cnblogs.com/wethura/p/9778451.html
Copyright © 2020-2023  润新知