[容斥原理] hdu 2461 Rectangles

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=2461

Rectangles

Time Limit: 5000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1268    Accepted Submission(s): 665

Problem Description

You are developing a software for painting rectangles on the screen. The software supports drawing several rectangles and filling some of them with a color different from the color of the background. You are to implement an important function. The function
answer such queries as what is the colored area if a subset of rectangles on the screen are filled.

Input

The input consists of multiple test cases. Each test case starts with a line containing two integers N(1 ≤ N ≤ 20) and M(1 ≤ M ≤ 100000), indicating the number of rectangles on the screen and the number of queries, respectively.

The i-th line of the following N lines contains four integers X1,Y1,X2,Y2 (0 ≤ X1 < X2 ≤ 1000, 0 ≤ Y1 < Y2 ≤ 1000), which indicate that the lower-left and upper-right coordinates of the i-th rectangle are (X1, Y1) and (X2, Y2). Rectangles are numbered from
1 to N.

The last M lines of each test case describe M queries. Each query starts with a integer R(1<=R ≤ N), which is the number of rectangles the query is supposed to fill. The following list of R integers in the same line gives the rectangles the query is supposed
to fill, each integer of which will be between 1 and N, inclusive.

The last test case is followed by a line containing two zeros.

Output

For each test case, print a line containing the test case number( beginning with 1).

For each query in the input, print a line containing the query number (beginning with 1) followed by the corresponding answer for the query. Print a blank line after the output for each test case.

Sample Input

2  2
0 0 2 2
1 1 3 3
1 1
2 1 2
2 1
0 1 1 2
2 1 3 2
2 1 2
0 0

Sample Output

Case 1:
Query 1: 4
Query 2: 7

Case 2:
Query 1: 2

Source

2008 Asia Hefei Regional Contest Online
by USTC

Recommend

teddy   |   We have carefully selected several similar problems for you:  2462 2463 2457 2458 2456

Statistic | Submit | Discuss | Note

题目意思:

给n(n<=20)个矩形,有m(m<=100000)个询问,每个询问求给定矩形的并的面积。

解题思路:

简单容斥原理

对于指定的矩形并面积,先求出所有单个矩形的和,再减去两个矩形的交,再加上三个矩形的交,以此类推。

问题就转化为求多个矩形的交,这个转化为求两个矩形的交。

代码:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define Maxn 33

struct Rec
{
    int x1,y1,x2,y2;
    bool vv;
}rec[Maxn];

int n,m,num,pp[Maxn],ans;

Rec cal(Rec a,Rec b) //求两个矩形的交的矩形
{
    Rec res;
    if(a.x1>b.x1)
        swap(a,b);

    if(b.x1>=a.x2||b.y1>=a.y2||b.y2<=a.y1)
    {
        res.vv=false;  //说明交的面积为0
        return res;
    }
    res.vv=true; //注意要置为true
    res.x1=b.x1;
    res.y1=max(a.y1,b.y1);

    res.x2=min(a.x2,b.x2);
    res.y2=min(a.y2,b.y2);

    return res;

}

int area(Rec cur)
{
    return (cur.x2-cur.x1)*(cur.y2-cur.y1);
}

void dfs(Rec hav,int cur,int cn)
{
    if(cur>num)
        return ;

    for(int i=cur;i<=num;i++)
    {
        Rec temp=cal(hav,rec[pp[i]]);

        if(!temp.vv)  //没有公共部分
            continue;

        if(cn&1)
            ans+=area(temp); //求公共部分面积
        else
            ans-=area(temp);

        dfs(temp,i+1,cn^1);
    }
}
int main()
{
   //freopen("in.txt","r",stdin);
   //freopen("out.txt","w",stdout);

   int ca=0;

   while(scanf("%d%d",&n,&m)&&n+m)
   {
       printf("Case %d:\n",++ca);

       for(int i=1;i<=n;i++)
           scanf("%d%d%d%d",&rec[i].x1,&rec[i].y1,&rec[i].x2,&rec[i].y2);

       for(int qu=1;qu<=m;qu++)
       {
           ans=0;

           scanf("%d",&num);
           for(int i=1;i<=num;i++)
               scanf("%d",&pp[i]);

           for(int i=1;i<=num;i++)
           {
               ans+=area(rec[pp[i]]);
               dfs(rec[pp[i]],i+1,0);

           }
           printf("Query %d: %d\n",qu,ans);

       }
       putchar(‘\n‘);
   }
   return 0;
}

[容斥原理] hdu 2461 Rectangles

时间: 2024-07-31 02:15:29

[容斥原理] hdu 2461 Rectangles的相关文章

HDU 2461 Rectangles#容斥原理

http://acm.hdu.edu.cn/showproblem.php?pid=2461 题目很简单,但是由于询问数M可以很大,所以容易超时,这道题学到了在结构体里面写函数的方法,这样子效率更高,否则的话,这道题就TLE了. 根据容斥原理,先把每个小长方形的面积加上,然后看有没有与该小长方形相交的,用dfs实现,当相交面积为0时,则不进行dfs,且同样遵循奇加偶减(但代码里因为是以第二个作为depth=1开始进行dfs的,所以是奇减偶加). AC代码: #include<iostream>

[容斥原理] hdu 4135 Co-prime

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4135 Co-prime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1176    Accepted Submission(s): 427 Problem Description Given a number N, you are a

[容斥原理] hdu 2204 Eddy&#39;s爱好

题意: 中文题目! 思路: 首先 M^k可以分解成 (M^(k*p)) p是素数 这么我们只要枚举素因子就好了 由于数据 所以只要枚举60以内的素数就够了 然后因为2*3*5*7就超过60了 做容斥原理就最多就只有三次 代码: #include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #inclu

[思维+容斥原理] hdu 2841 Visible Trees

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2841 Visible Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1337    Accepted Submission(s): 552 Problem Description There are many trees f

HDU 2056 Rectangles(计算相交面积)

Rectangles Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 20183    Accepted Submission(s): 6537 Problem Description Given two rectangles and the coordinates of two points on the diagonals of e

[容斥原理] hdu 1796 How many integers can you find

题意: 给一个N,然后给M个数,问1~N-1里面有多少个数能被这M个数中一个或多个数整除. 思路: 首先要N-- 然后对于每个数M 其实1~N-1内能被其整除的 就是有(N-1)/M[i]个 但是会出现重复 比如 样例 6就会被重复算 这时候我们就需要容斥原理了 加上一个数的减去两个数的.. 这里要注意了 两个数以上的时候 是求LCM而不是简单的相乘! 代码: #include "stdio.h" #include "string.h" #include "

[容斥原理] hdu 1695 GCD

题意: 给你a,b,c,d,k问 x∈[a,b] y∈[c,d],gcd(x,y)=k 的个数 然后重复算一种 也就是 x=1,y=2和x=2,y=1是一样的. 思路: 首先将b/k,d/k 就转换成了 x∈[a,b] y∈[c,d],gcd(x,y)=1的个数 然后我们枚举其中一个长度较小的区间 找另一个区间与它互质的数 因为数很多,需要预处理一下每个数的质因子 然后就是容斥定理搞了! 然后要注意0的情况! 代码: #include"cstdlib" #include"cs

[容斥原理] hdu 4407 Sum

题意: 有两种操作1,2 1:询问 x,y区间能与p互质的数的和 2:将x改成p 一开始给N,初始是1~N个数 思路: 我们在求不互质的数有多少个的时候 其实就可以用等差数列求和求出这些数的和 那么我们到时候直接求一下就好了 然后因为这里的操作次数很少 所以我们可以标记一下哪些位置被修改过 然后在1操作的时候 特判一下这些位置 代码: #include"cstdlib" #include"cstdio" #include"cstring" #in

HDU 2056 Rectangles

这题就是简单的几何题,刚接触ACM做这题时,不会写,当时想的太复杂了,把矩形的各种情况组合都考虑到了,结果发现这样太复杂就放弃了.今天做这道题时,我突然发现既然题目给的是对角线的坐标,为什么不用对角线之间的关系来判别矩形之间的位置关系呢?于是思路就很简单的涌现出来了.只要画个图,就能明白两者之间对角线的关系. #include<cstdio> #include<cstring> #include<algorithm> double _max(double x,doubl