晒被子

【题目描述】:

在平面直角坐标系上晒了许多块被子,被子呈矩形,边均与x或y轴平行,在(0,0)处有一个水源,水不断从(0,0)处溢出,在第t秒形成了一个以(0,0)(0,t)(t,0)(t,t)为顶点的正方形水域,在其中的被子都会被弄湿,询问某些时刻被弄湿的被子的总面积(同一格子的不同被子算多次)。

【输入描述】:

第一行2个整数n、q,表示被子总数和询问次数。

接下来n行每行4个整数x1、y1、x2、y2,表示一条被子的位置是以(x1,y1)(x2,y2)为左下角和右上角顶点的矩形。

接下来q行每行1个整数t,表示询问第t秒被子弄湿的总面积。

【输出描述】:

共q行表示每次询问的答案。

【样例输入】:

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

【样例输出】:

1
8
17

【样例说明】:

样例输入说明,下载图片

【时间限制、数据范围及描述】:

时间:1s 空间:256M

30%的数据0<=t,x1,y1,x2,y2<=1000。

50%的数据n<=1000,q<=1000。

另有20%的数据q=1。

100%的数据n<=50000,q<=100000,0<=t,x1,y1,x2,y2<=5×10^6,x1<x2,y1<y2。

下载

中文

【code】

 1 #include <cstdio>
 2 int n,m,i,x1,y1,x2,y2,t,l,a[500001],b[500001],c[500001],x,d[400001];
 3 long long t1,t2,tot,s,s2,ss,ans[100001];
 4 bool p[400001];
 5 void add(int x,int y,int z)
 6 {
 7     if (x>y) t=x,x=y,y=t;s+=z;
 8     ++l;a[l]=x;b[l]=(l+1)/2;c[l]=z;
 9     ++l;a[l]=y;b[l]=l/2;c[l]=z;
10 }
11 void kp(int l,int r)
12 {
13     int i=l,j=r,m=a[(i+j)/2];
14     while (i<=j)
15     {
16         while (a[i]<m) ++i;
17         while (a[j]>m) --j;
18         if (i<=j)
19         {
20             t=a[i];a[i]=a[j];a[j]=t;
21             t=b[i];b[i]=b[j];b[j]=t;
22             t=c[i];c[i]=c[j];c[j]=t;
23             ++i;--j;
24         }
25     }
26     if (i<r) kp(i,r);if (l<j) kp(l,j);
27 }
28 int main()
29 {
30     scanf("%d%d",&n,&m);s=0;
31     for (i=1;i<=n;++i)
32     {
33         scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
34         if (x2>0&&y2>0) add(x2,y2,1);
35         if (x1>0&&y2>0) add(x1,y2,-1);
36         if (x2>0&&y1>0) add(x2,y1,-1);
37         if (x1>0&&y1>0) add(x1,y1,1);
38     }
39     for (i=1;i<=m;++i)
40     {
41         scanf("%d",&x);++l;a[l]=x;b[l]=i;c[l]=0;
42     }
43     kp(1,l);tot=0;s2=0;a[0]=0;
44     for (i=1;i<=l;++i)
45     {
46         t1=a[i-1];t2=a[i];ss=t2*t2-t1*t1;
47         tot+=ss*s;ss=(t2-t1)*s2;tot+=ss;
48         if (c[i]==0) ans[b[i]]=tot;else
49         if (!p[b[i]])
50         {
51             s2+=a[i]*c[i];s-=c[i];p[b[i]]=true;d[b[i]]=a[i];
52         } else s2-=d[b[i]]*c[i];
53     }
54     for (i=1;i<=m;++i) printf("%lld\n",ans[i]);
55 }

猜你喜欢

转载自www.cnblogs.com/66dzb/p/11349081.html