cdq分治——bzoj2683简单题

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

知识点:1.以操作的顺序进行分治

        2.cdq分治维护矩阵

               3.计算比mid小的给比mid大的的贡献

    4.容斥原理

code:

#include <bits/stdc++.h>
#define inf 1000000002
#define ll long long 
using namespace std;
int s,w,m;
int ans[10005];
int t[2000005];
struct que
{
    int x,y;
    int val,pos;
    int id,opt;
}q[200005],tmp[200005];
bool operator < (que a,que b)
{
    if(a.x == b.x && a.y == b.y)return a.opt < b.opt;
    if(a.x == b.x)return a.y < b.y;
    return a.x < b.x;
}
void addquery()
{
    int x1,y1,x2,y2;
    scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
    int pos = ++ans[0];
    q[++m].pos = pos;q[m].id = m;q[m].x = x1 - 1;q[m].y=y1 - 1;q[m].val = 1;q[m].opt = 1;
    q[++m].pos = pos;q[m].id = m;q[m].x = x2;q[m].y = y2;q[m].val = 1;q[m].opt = 1;
    q[++m].pos = pos;q[m].id = m;q[m].x = x1 - 1;q[m].y = y2;q[m].val = -1;q[m].opt = 1;
    q[++m].pos = pos;q[m].id = m;q[m].x = x2;q[m].y = y1 - 1;q[m].val = -1;q[m].opt = 1;
}
int lowbit(int x)
{
    return x&(-x);
}
void add(int x,int val)
{
    for(int i=x;i<=w;i+=i&-i)t[i]+=val;
}
int query(int x)
{
    int tmp = 0;
    for(int i = x;i;i -= lowbit(i))tmp += t[i];
    return tmp;
}
void cdq(int l,int r)
{
    if(l == r)return;
    int mid = (l + r) >> 1,l1 = l,l2 = mid + 1;
    for(int i = l;i <= r;i++)
    {
        if(q[i].id <= mid&&!q[i].opt)add(q[i].y,q[i].val);
        if(q[i].id > mid && q[i].opt)ans[q[i].pos] += q[i].val * query(q[i].y);
    }
    for(int i = l;i <= r;i++)
        if(q[i].id <= mid && !q[i].opt)add(q[i].y,-q[i].val);
    for(int i = l;i <= r;i++)
        if(q[i].id <= mid)tmp[l1++] = q[i];
        else tmp[l2++] = q[i];
    for(int i = l;i <= r;i++)
        q[i] = tmp[i];
    cdq(l,mid);cdq(mid + 1,r);
}
int main()
{
    scanf("%d%d",&s,&w);
    while(1)
    {
        int opt;
        scanf("%d",&opt);
        if(opt == 1)
        {
            m++;
            scanf("%d%d%d",&q[m].x,&q[m].y,&q[m].val);
            q[m].id = m;
        }
        else if(opt == 2)
            addquery();
        else break;
    }
    sort(q + 1,q + m + 1);
    cdq(1,m);
    for(int i = 1;i <= ans[0];i++)
        printf("%d\n",ans[i]);
    return 0;
}

 

posted @ 2019-07-09 19:12  ywwywwyww  阅读(160)  评论(0编辑  收藏  举报