【HDU】2461 Rectangles

题意:不超过20个矩形,100000个询问,求矩形面积并。

线段树复杂度比较靠谱吧。

偷懒用容斥了。由于询问很多,容斥时候会重复用到某几个矩形的面积交,那么可以先预处理出来。

询问的时候枚举子集肯定会TLE的,如果当前面积交为0,就不要再DFS下去了。这样就水过去了。

 1 #include<cstdio>

 2 #include<algorithm>

 3 #define MAXN 20

 4 #define MAX(a,b) ((a)>(b)?(a):(b))

 5 #define MIN(a,b) ((a)<(b)?(a):(b))

 6 #define oo 0x7FFFFFFF

 7 using namespace std;

 8 struct Rec {

 9     int x1, y1, x2, y2;

10 };

11 Rec r[MAXN];

12 int depth, tot, cnt, pos[MAXN], area[1 << MAXN];

13 int Get(int x) {

14     int i;

15     Rec tmp;

16     tmp.x1 = tmp.y1 = 0;

17     tmp.x2 = tmp.y2 = oo;

18     for (i = 0; x; x >>= 1, i++) {

19         if (x & 1) {

20             tmp.x1 = MAX(tmp.x1,r[i].x1);

21             tmp.y1 = MAX(tmp.y1,r[i].y1);

22             tmp.x2 = MIN(tmp.x2,r[i].x2);

23             tmp.y2 = MIN(tmp.y2,r[i].y2);

24         }

25     }

26     if (tmp.x2 <= tmp.x1)

27         return 0;

28     if (tmp.y2 <= tmp.y1)

29         return 0;

30     return (tmp.x2 - tmp.x1) * (tmp.y2 - tmp.y1);

31 }

32 void DFS(int index, int now, int state) {

33     if (state && !area[state])

34         return;

35     if (cnt - index < depth - now)

36         return;

37     if (now == depth)

38         tot += area[state];

39     else {

40         int i;

41         for (i = index; i < cnt; i++)

42             DFS(i + 1, now + 1, state | (1 << (pos[i] - 1)));

43     }

44 }

45 int Count() {

46     int ans;

47     ans = 0;

48     for (depth = 1; depth <= cnt; depth++) {

49         tot = 0;

50         DFS(0, 0, 0);

51         if (depth & 1)

52             ans += tot;

53         else

54             ans -= tot;

55     }

56     return ans;

57 }

58 int main() {

59     int ca = 1;

60     int n, q;

61     int i, j;

62     while (scanf("%d%d", &n, &q), n) {

63         for (i = 0; i < n; i++)

64             scanf("%d%d%d%d", &r[i].x1, &r[i].y1, &r[i].x2,

65                     &r[i].y2);

66         for (i = 1; i < (1 << n); i++)

67             area[i] = Get(i);

68         printf("Case %d:\n", ca++);

69         for (j = 1; j <= q; j++) {

70             scanf("%d", &cnt);

71             for (i = 0; i < cnt; i++)

72                 scanf("%d", &pos[i]);

73             sort(pos, pos + cnt);

74             cnt = unique(pos, pos + cnt) - pos;

75             printf("Query %d: %d\n", j, Count());

76         }

77         putchar('\n');

78     }

79     return 0;

80 }

你可能感兴趣的:(HDU)