二维前缀和、差分习题集

佐手、 提交于 2019-11-27 04:04:11

https://blog.csdn.net/K_R_forever/article/details/81775899

1、HDU6514 Monitor

先给p个矩形,再给q个矩形,q个矩形中若能被p个矩形所在区域包含则YES,否则NO。转化为二维差分问题。

 1 #include<iostream>
 2 #include<sstream>
 3 #include<fstream>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<iomanip>
 7 #include<cstdlib>
 8 #include<cctype>
 9 #include<vector>
10 #include<string>
11 #include<cmath>
12 #include<ctime>
13 #include<stack>
14 #include<queue>
15 #include<map>
16 #include<set>
17 #define mem(a,b) memset(a,b,sizeof(a))
18 #define random(a,b) (rand()%(b-a+1)+a)
19 #define ll long long
20 #define ull unsigned long long
21 #define e 2.71828182
22 #define Pi acos(-1.0)
23 #define ls(rt) (rt<<1)
24 #define rs(rt) (rt<<1|1)
25 #define lowbit(x) (x&(-x))
26 using namespace std;
27 const int MAXN=1e7+5;
28 int a[MAXN];
29 int n,m,p,q;
30 int pos(int x,int y)
31 {
32     if(x<1||y<1||x>n||y>m) return 0;
33     return (x-1)*m+y;
34 }
35 void add(int x,int y,int k)
36 {
37     if(!pos(x,y)) return;
38     a[pos(x,y)]+=k;
39 }
40 int query(int x,int y)
41 {
42     if(!pos(x,y)) return 0;
43     return a[pos(x,y)];
44 }
45 int read()
46 {
47     int s=1,x=0;
48     char ch=getchar();
49     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
50     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
51     return x*s;
52 }
53 int main()
54 {
55     while(~scanf("%d%d",&n,&m))
56     {
57         mem(a,0);
58         p=read();
59         for(int i=1;i<=p;++i)
60         {
61             int x1=read(),y1=read(),x2=read(),y2=read();
62             add(x1,y1,1);add(x2+1,y2+1,1);
63             add(x2+1,y1,-1);add(x1,y2+1,-1);
64         }
65         
66         //因为a数组初始化为0,计算后a[x,y]为二维前缀和,
67         //即代表p区域的个数 
68         for(int i=1;i<=n;++i)
69         for(int j=1;j<=m;++j)
70         a[pos(i,j)]+=query(i,j-1)+query(i-1,j)-query(i-1,j-1);
71         
72         //a[x,y]只要大于1,说明有p区域 ,赋值为1 
73         for(int i=1;i<=n;++i)
74         for(int j=1;j<=m;++j)
75         a[pos(i,j)]=a[pos(i,j)]>0;
76         
77         //再计算一遍前缀和,a[x,y]代表[0,0]到[x,y]p区域标记的大小 
78         for(int i=1;i<=n;++i)
79         for(int j=1;j<=m;++j)
80         a[pos(i,j)]+=query(i,j-1)+query(i-1,j)-query(i-1,j-1);
81         
82         q=read();
83         for(int i=1;i<=q;++i)
84         {
85             int x1=read(),y1=read(),x2=read(),y2=read();
86             int A=(x2-x1+1)*(y2-y1+1);
87             int B=query(x2,y2)+query(x1-1,y1-1)-query(x2,y1-1)-query(x1-1,y2);
88             //要完全覆盖 
89             if(A==B) puts("YES");
90             else puts("NO");
91         }
92     }
93     return 0;
94 }
View Code

也可以用二维数组,代码明天补

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!