poj 3695 Rectangles 容斥原理 求矩形面积并

题目链接:http://poj.org/problem?id=3695

题意:给你n个矩形,m个询问,每个询问是问几个矩形的面积并

由于n很小,所以把询问存下来,把所有的询问的情况状压记录,O(1)输出

记录的时候对于相交的矩形的面积可以用容斥原理求解,20个矩形的话dfs处理就好了

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define ll long long

using namespace std;
const int maxn = 1e5 + 10;
const int INF = 0x3f3f3f3f;
struct node{
    int x1, x2, y1, y2;
}pos[21];

int n, m, ask[maxn], ans[1 << 21];

void dfs(int x1, int y1, int x2, int y2, int deep, int sign, int sta){
    if(x1 >= x2 || y1 >= y2)  return;
    if(deep == n){
        if(sta){
            for(int i = 0; i < m; i++) {
                if((ask[i] | sta) == ask[i]){
                    ans[ask[i]] += sign * (x2 - x1) * (y2 - y1);
                }
            }
        }
        return;
    }
    int xx1 = max(x1, pos[deep].x1);
    int xx2 = min(x2, pos[deep].x2);
    int yy1 = max(y1, pos[deep].y1);
    int yy2 = min(y2, pos[deep].y2);
    dfs(x1, y1, x2, y2, deep + 1, sign, sta);
    dfs(xx1, yy1, xx2, yy2, deep + 1, -sign, sta | (1 << deep));
}

int main() {
    int t = 1;
    while(scanf("%d%d", &n, &m) && n && m){
        for(int i = 0; i < n; i++) {
            scanf("%d%d%d%d",&pos[i].x1, &pos[i].y1, &pos[i].x2, &pos[i].y2);
        }
        for(int i = 0; i < m; i++)ask[i] = 0;
        for(int i = 0; i < (1 << 21); i++) ans[i] = 0;
        for(int i = 0; i < m; i++) {
            int q, x;
            scanf("%d", &q);
            while(q--) {
                scanf("%d", &x);
                ask[i] |= (1 << (x - 1));
            }
        }
        dfs(0, 0, INF, INF, 0, -1, 0);
        printf("Case %d:\n", t++);
        for(int i = 0; i < m; i++) {
            printf("Query %d: %d\n", i + 1, ans[ask[i]]);
        }
        printf("\n");
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值