[Balkan 2007] Mokia

[题目链接]

         https://www.lydsy.com/JudgeOnline/problem.php?id=1176

[算法]

       CDQ分治 + 树状数组即可

       时间复杂度 : O(Nlog^2N)

[代码]

        

#include<bits/stdc++.h>
using namespace std;
const int N = 160010;
const int M = 2000010;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

struct Query
{
        int pos , x , y , value , type , id;
} q[N * 5] , t1[N * 5] , t2[N * 5];

int s , w , m , k;
int c[M] , ans[N];

template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
    x *= f;
}
inline bool cmp(Query a , Query b)
{
        if (a.x != b.x) return a.x < b.x;
        else if (a.y != b.y) return a.y < b.y;
        else return a.type < b.type;        
}
inline int lowbit(int x)
{
        return x & (-x);
}
inline void modify(int x , int val)
{
        for (int i = x; i <= w; i += lowbit(i))
                c[i] += val;
}
inline int query(int x)
{
        int ret = 0;
        for (int i = x; i; i -= lowbit(i))
                ret += c[i];
        return ret;
}
inline void cdq(int l , int r)
{
        int mid = (l + r) >> 1;
        if (l == r) return;
        for (int i = l; i <= r; i++)
        {
                if (q[i].type == 1 && q[i].pos <= mid) modify(q[i].y , q[i].value);
                else if (q[i].type == 2 && q[i].pos > mid) ans[q[i].id] += q[i].value * query(q[i].y);
        }
        for (int i = l; i <= r; i++)
        {
                if (q[i].type == 1 && q[i].pos <= mid)
                        modify(q[i].y , -q[i].value);
        }
        int l1 = 0 , l2 = 0;
        for (int i = l; i <= r; i++)
                if (q[i].pos <= mid) t1[++l1] = q[i];
                else t2[++l2] = q[i];
        for (int i = 1; i <= l1; i++) q[l + i - 1] = t1[i];
        for (int i = 1; i <= l2; i++) q[l + l1 + i - 1] = t2[i];
        cdq(l , mid);
        cdq(mid + 1 , r);
}

int main()
{
        
        read(s); read(w);
        while (true)
        {
                int type;
                read(type);
                if (type == 3) break;
                if (type == 1)
                {
                        int x , y , a;
                        read(x); read(y); read(a);
                        q[++m] = (Query){m , x , y , a , 1 , k};
                } else
                {
                        int X1 , Y1 , X2 , Y2;
                        read(X1); read(Y1); read(X2); read(Y2);
                        ans[++k] = s * (X2 - X1 + 1) * (Y2 - Y1 + 1);
                        q[++m] = (Query){m , X2 , Y2 , 1 , 2 , k};
                        q[++m] = (Query){m , X1 - 1 , Y2 , -1 , 2 , k};
                        q[++m] = (Query){m , X2 , Y1 - 1 , -1 , 2 , k};
                        q[++m] = (Query){m , X1 - 1 , Y1 - 1 , 1 , 2 , k};
                }
        }
        sort(q + 1 , q + m + 1 , cmp);
        cdq(1 , m);
        for (int i = 1; i <= k; i++) printf("%d
" , ans[i]);
        
        return 0;
    
}
原文地址:https://www.cnblogs.com/evenbao/p/10360004.html