zoukankan      html  css  js  c++  java
  • BZOJ 2683 简单题 ——CDQ分治

    【题目分析】

        感觉CDQ分治和整体二分有着很本质的区别。

        为什么还有许多人把他们放在一起,也许是因为代码很像吧。

        CDQ分治最重要的是加入了时间对答案的影响,x,y,t三个条件。

        排序解决了x ,分治解决了t ,树状数组解决了y。

        时间复杂度,排序log,分治log,树状数组也是log

        分治中加入了树状数组,所以复杂度带两个log

        而整体二分完全没有时间的先后,所以只有一个log。

        CDQ分治,分治的是时间。

        整体二分,分治的是答案。

        还是很不同的算法。

    【代码】

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define MAXN 800010
    #define SIZE 500010
    #define lowbit(x) (x&(-x))
    using namespace std;
    int w;
    int top,opt,L,R,l,r,delta,Top;
    struct Query
    {
        int op;
        int x,y,A;
        int t,id;
        bool operator <(const Query& a)const
        {
            if (x == a.x && y == a.y) return op < a.op;
            if (x == a.x) return y < a.y;
            return x < a.x;
        }
    }que[MAXN],newq[MAXN];
    long long ans[MAXN],c[SIZE];
    inline void in(int &x)
    {
        x=0;char ch = getchar();
        while (!(ch >= '0' && ch <= '9'))   ch = getchar();
        while (ch >= '0' && ch <= '9')  x = x * 10 + ch - '0',ch = getchar();
    }
    inline void add(int i,long long x)
    {
        while (i && i <= w) c[i] += x,i += lowbit(i);
    }
    inline long long query(int i)
    {
        long long ret = 0;
        while (i) ret += c[i],i -= lowbit(i);
        return ret;
    }
    inline void Solve(int l,int r)
    {
        int mid = (l + r) >> 1,tp1 = l,tp2 = mid + 1;
        if (l == r) return;
        for (int i = l;i <= r;i++)
        {
            if (que[i].t <= mid && que[i].op == 1)  add(que[i].y,que[i].A);
            if (que[i].t > mid && que[i].op == 2)   ans[que[i].id] += query(que[i].y) * que[i].A;
        }
        for (int i = l;i <= r;i++)
            if (que[i].t <= mid && que[i].op == 1) add(que[i].y,-que[i].A);
        for (int i = l;i <= r;i++)
            if (que[i].t <= mid) newq[tp1++] = que[i];
            else newq[tp2++] = que[i];
        memcpy(que+l,newq+l,sizeof(Query)*(r - l + 1));
        Solve(l,mid);Solve(mid+1,r);
    }
    int main()
    {
        in(w);
        while (1)
        {
            in(opt);
            if (opt == 3) break;
            switch (opt)
            {
                case 1:
                    in(L);in(R);in(delta);
                    que[++top].op = opt;que[top].x = L;que[top].y = R;que[top].A = delta;que[top].t = top;
                    break;
                case 2:
                    in(L);in(R);in(l);in(r);
                    que[++top].op = opt;que[top].x = L - 1;que[top].y = R - 1;que[top].t = top;que[top].A = 1;que[top].id = ++Top;
                    que[++top].op = opt;que[top].x = L - 1;que[top].y = r;que[top].t = top;que[top].A = -1;que[top].id = Top;
                    que[++top].op = opt;que[top].x = l;que[top].y = R - 1;que[top].t = top;que[top].A = -1;que[top].id = Top;
                    que[++top].op = opt;que[top].x = l;que[top].y = r;que[top].t = top;que[top].A = 1;que[top].id = Top;
                    break;
            }
        }
        sort(que + 1,que + top + 1);
        Solve(1,top);
        for (int i = 1;i <= Top;i++)    printf("%lld
    ",ans[i]);
    }
    

      

  • 相关阅读:
    map & reduce
    Generator
    切片
    函数参数
    Dict & Set
    list,tuple
    selenium鼠标和键盘操作
    selenium元素定位以及点击事件
    css定位
    xpath
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6229501.html
Copyright © 2011-2022 走看看