HDU4533 威威猫系列故事――晒被子

来源:互联网 发布:福州seo基础培训 编辑:程序博客网 时间:2024/04/30 00:54

题目大意

转向题目

在坐标系里面给定了N个矩形,有M次询问,每次询问输入一个t,询问的是从(0,0)到(t,t)范围内的矩形的面积(重叠也算,不是矩形面积并)


解题思路

这道题很容易让人联想到二维的做法,但是我们一看数据范围,发现是20W,明显无法满足空间限制,那么应该怎么办呢?
首先,矩形是无更新的,这给我们了非常大的空间,那么我们就可以想办法得到每一个位置的函数表达式
既然只有一个t是变元,我们可以假定t是自变量,既然是面积,一定是一个二次函数的模型
假设S=a*t^2+b*t+c,那么我们可以用三个树状数组(或线段树)维护每一个位置的啊a,b和c,我们要求的不是矩形面积并,便可以单个矩形考虑,这样就分出来三种情况
给定范围和矩形部分相交,完全含住矩形和有一条边和矩形一条边重合,由于范围是正方形,我们便需要考虑矩形的点的x坐标和y坐标的关系。
具体的就是如果x2<y2就需要考虑竖相交的诸多情况,如果x2>y2就需要考虑竖相交的诸多情况

AC代码

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>using namespace std;typedef long long LL;const int maxn = (int)2e5 + 10;struct Bitarray{    LL T[maxn];    int lowbit(int x){return x & (-x);}    void clear(){memset(T, 0, sizeof(T));}    void add(int st, int ed, LL val){        for (int i = st; i < maxn; i += lowbit(i)) T[i] += val;        for (int i = ed + 1; i < maxn; i += lowbit(i)) T[i] -= val;    }    LL query(int pos){        LL sum = 0;        for (int i = pos; i > 0; i -= lowbit(i)) sum += T[i];        return sum;    }}A, B, C;void fun(int st, int ed, LL a, LL b, LL c){    A.add(st, ed, a);    B.add(st, ed, b);    C.add(st, ed, c);}int n, m;void solve(){    A.clear(); B.clear(); C.clear();    scanf("%d", &n);    LL x1, x2, y1, y2;    for (int i = 0; i < n; i++){        scanf("%I64d%I64d%I64d%I64d", &x1, &y1, &x2, &y2);        if (max(x1, y1) < min(x2, y2))            fun(max(x1, y1), min(x2, y2), 1, -(x1 + y1), x1 * y1);        if (x2 < y2) fun(max(x2, y1) + 1, y2, 0, -x1 + x2, y1 * (x1 - x2));          if (y2 < x2) fun(max(y2, x1) + 1, x2, 0, -y1 + y2, x1 * (y1 - y2));        fun(max(x2, y2) + 1, maxn, 0, 0, (x2 - x1) * (y2 - y1));    }    scanf("%d", &m);    while(m--){        LL t;        scanf("%I64d", &t);        LL ans = 0;        ans += A.query(t) * t * t;        ans += B.query(t) * t;        ans += C.query(t);        printf("%I64d\n", ans);    }}int main(){    #ifndef ONLINE_JUDGE    freopen("in.txt", "rt", stdin);    #endif    int cs; cin >> cs;    while(cs--) solve();    return 0;}