Problem Description
  因为马拉松初赛中吃鸡腿的题目让不少人抱憾而归,威威猫一直觉得愧对大家,这几天他悄悄搬到直角坐标系里去住了。

  生活还要继续,太阳也照常升起,今天,威威猫在第一象限晒了N条矩形的被子,被子的每条边都和坐标轴平行,不同被子的某些部分可能会叠在一起。这时候,在原点处突然发了场洪水,时间t的时候,洪水会蔓延到( t, t ),即左下角为( 0, 0 ) ,右上角为( t, t )的矩形内都有水。

  悲剧的威威猫想知道,在时间t1, t2, t3 ... tx 的时候,他有多少面积的被子是湿的?
 

Input
输入数据首先包含一个正整数T,表示有T组测试数据;

每组数据的第一行首先是一个整数N,表示有N条被子;

接下来N行,每行包含四个整数x1, y1, x2, y2,代表一条被子的左下角和右上角的坐标;

然后接下来一行输入一个整数x,表示有x次询问;

再接下来x行,输入x个严格单调递增的整数,每行一个,表示威威猫想知道的时间ti。

[Technical Specification]

T <= 5

0 < N <= 20000

1 <= x1 < x2 <= 200000

1 <= y1 < y2 <= 200000

1 <= x <= 20000

1 <= ti <= 200000 (1 <= i <= x )
 

Output
对于每次询问,请计算并输出ti时有多少面积的被子是湿的,每个输出占一行。
 

Sample Input

1
2
1 1 3 3
2 2 4 4
5
1
2
3
4
5
 

Sample Output

0
1
5
8
8

这题里求的面积是各个矩形的面积和,并不是矩形面积的并,即相互不影响,因为对于各个时段,矩形的面积都可以用A*t^2+B*t+C表示,所以我们可以用树状数组或者线段树分别维护A,B,C,每次读入一个矩形,就记录它对不同时间段t的影响,然后把相应的系数加到线段树中。

当一个矩形读入时(左下角坐标(x1,y1),右上角坐标(x2,y2)),有四种影响情况:

1.0~max(x1,y1) 这个时期因为t时间形成的矩形在该矩形下面,对面积没有影响,所以不用考虑。

2.如果存在t时间形成的矩形部分覆盖该矩形,但没有碰到或者超过该矩形的上边或者右边,那么要同时更新A,B,C,表达式为(t-x1)*(t-y1)。这里的判断表达式为如果(max(x1,y1)<min(x2,y2)),则更新max(x1,y1)~min(x2,y2)。

3.t时间内形成的矩形恰好碰到或者越过右边或上边的一条,即这段时间内的矩形面积变化中(x2-x1)或(y2-y1)为常数,那么要更新,注意,这里更新的时候要分类讨论,具体看代码。

4.max(x2,y2)~maxn,这个时期因为t时间形成的矩形已经完全覆盖矩形,所以要更新C,加上面积常数。

写线段树的时候注意,三个变量要一起存,不能开三个线段树,会超内存的。

线段树代码:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
#define ll __int64
#define maxn 200050
ll A,B,C;
ll a[10];
struct node{
ll l,r,cnt1,cnt2,cnt3,flag;
}b[4*maxn]; void build(ll l,ll r,ll i)
{
ll mid;
b[i].l=l;b[i].r=r;b[i].cnt1=b[i].cnt2=b[i].cnt3=0;b[i].flag=1;
if(l==r)return;
mid=(l+r)/2;
build(l,mid,i*2);
build(mid+1,r,i*2+1);
}
void update(ll l,ll r,ll a[],ll i)
{
ll mid;
if(b[i].l==l && b[i].r==r){
b[i].cnt1+=a[1];b[i].cnt2+=a[2];b[i].cnt3+=a[3];return;
}
mid=(b[i].l+b[i].r)/2;
if(r<=mid)update(l,r,a,i*2);
else if(l>mid)update(l,r,a,i*2+1);
else{
update(l,mid,a,i*2);
update(mid+1,r,a,i*2+1);
}
} void question(ll id,ll i)
{
ll mid;
if(b[i].l==id && b[i].r==id){
A=b[i].cnt1;B=b[i].cnt2;C=b[i].cnt3;return;
}
if(b[i].cnt1){
b[i*2].cnt1+=b[i].cnt1;
b[i*2+1].cnt1+=b[i].cnt1;
b[i].cnt1=0;
}
if(b[i].cnt2){
b[i*2].cnt2+=b[i].cnt2;
b[i*2+1].cnt2+=b[i].cnt2;
b[i].cnt2=0;
}
if(b[i].cnt3){
b[i*2].cnt3+=b[i].cnt3;
b[i*2+1].cnt3+=b[i].cnt3;
b[i].cnt3=0;
}
mid=(b[i].l+b[i].r)/2;
if(id<=mid)question(id,i*2);
else question(id,i*2+1);
} int main()
{
ll i,j,x1,x2,y1,y2,t,t1,t2;
int T,n,m;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
build(1,maxn,1);
for(i=1;i<=n;i++){
scanf("%I64d%I64d%I64d%I64d",&x1,&y1,&x2,&y2);
if(max(x1,y1)<min(x2,y2)){
a[1]=1;a[2]=-(x1+y1);a[3]=x1*y1;
update(max(x1,y1),min(x2,y2)-1,a,1);
} if(x2<y2){
a[1]=0;a[2]=-x1+x2;a[3]=y1*(x1-x2);
update(max(x2,y1),y2-1,a,1);
}
if(y2<x2){
a[1]=0;a[2]=-y1+y2;a[3]=x1*(y1-y2);
update(max(y2,x1),x2-1,a,1);
}
a[1]=0;a[2]=0;a[3]=(x2-x1)*(y2-y1);
update(max(x2,y2),maxn,a,1); }
scanf("%d",&m);
for(i=1;i<=m;i++){
scanf("%I64d",&t);
A=B=C=0;
question(t,1);
printf("%I64d\n",A*t*t+B*t+C);
}
}
return 0;
}

树状数组代码://速度快了一倍= =

#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 200010
#define ll __int64
using namespace std;
ll max(ll a,ll b){
return a>b?a:b;
}
ll min(ll a,ll b){
return a<b?a:b;
} struct segment{
ll b[maxn],ans;
void clear(){
memset(b,0,sizeof(b));
}
int lowbit(ll x){
return x&(-x);
}
void update(ll pos,ll num){
while(pos<=maxn){
b[pos]+=num;pos+=lowbit(pos);
}
}
ll getsum(ll pos){
ans=0;
while(pos>0){
ans+=b[pos];pos-=lowbit(pos);
}
return ans;
}
}A,B,C; void fun(ll l,ll r,ll num1,ll num2,ll num3){
A.update(l,num1);A.update(r+1,-num1);
B.update(l,num2);B.update(r+1,-num2);
C.update(l,num3);C.update(r+1,-num3);
} int main()
{ int t;
scanf("%d",&t);
while(t--)
{
A.clear(); B.clear(); C.clear();
int n,m;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
ll x1,y1,x2,y2;
scanf("%I64d%I64d%I64d%I64d",&x1,&y1,&x2,&y2); if(max(x1,y1)<min(x2,y2))
fun(max(x1,y1),min(x2,y2),1,-(x1+y1),x1*y1); if(x2<y2) fun(max(x2,y1)+1,y2,0,-x1+x2,y1*(x1-x2));
if(y2<x2) fun(max(y2,x1)+1,x2,0,-y1+y2,x1*(y1-y2)); fun(max(x2,y2)+1,maxn,0,0,(x2-x1)*(y2-y1));
} scanf("%d",&m);
while(m--)
{
ll t;
scanf("%I64d",&t);
ll ans=0;
ans+=A.getsum(t)*t*t;
ans+=B.getsum(t)*t;
ans+=C.getsum(t); printf("%I64d\n",ans);
}
}
return 0;
}

hdu4533 威威猫系列故事——晒被子的更多相关文章

  1. HDU-4533 威威猫系列故事——晒被子(区间更新)

    题目大意:在平面直角坐标系的第一象限中,给出n个矩形(可能重叠).有m次询问,每次询问点(t,t)的左下方的正方形区域中矩形的总面积(重叠部分重叠几次就得统计几次). 题目分析:线段树的叶子节点x维护 ...

  2. HDU 4533 威威猫系列故事——晒被子

    题目链接 扫描线可做,然后当时比赛后问虎哥,他说可以标记,然后拖了很久,今天从早上折腾到晚上,终于把两种情况写出来,分析太弱.改天扫描线,再来一次. 被子如果被y = x 穿过,可以分成两部分,上和下 ...

  3. HDU 4540 威威猫系列故事——打地鼠

    威威猫系列故事--打地鼠 Time Limit: 300/100 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Su ...

  4. hdu 4523 威威猫系列故事——过生日 小模拟

    威威猫系列故事——过生日 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total ...

  5. hdu 4540 威威猫系列故事——打地鼠 dp小水题

    威威猫系列故事——打地鼠 Time Limit: 300/100 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total ...

  6. HDU--杭电--4504--威威猫系列故事——篮球梦--DP

    威威猫系列故事——篮球梦 Time Limit: 300/100 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total ...

  7. HDU 4540 威威猫系列故事——打地鼠 (状态压缩DP)

    威威猫系列故事——打地鼠 Time Limit: 300/100 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total ...

  8. HDUOJ----4504 威威猫系列故事——篮球梦

    威威猫系列故事——篮球梦 Time Limit: 300/100 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total ...

  9. hdoj 4526 威威猫系列故事——拼车记

    威威猫系列故事——拼车记 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total ...

随机推荐

  1. PAT甲级 1155 Heap Paths (30分) 堆模拟

    题意分析: 给出一个1000以内的整数N,以及N个整数,并且这N个数是按照完全二叉树的层序遍历输出的序列,输出所有的整条的先序遍历的序列(根 右 左),以及判断整棵树是否是符合堆排序的规则(判断是大顶 ...

  2. ajax跨域访问http服务--jsonp

    在前面一篇文章<Spring Cloud 前后端分离后引起的跨域访问解决方案>里我们提到使用ajax跨域请求其他应用的http服务,使用的是后台增加注解@CrossOrigin或者增加Co ...

  3. pyi文件是干嘛的?(一文读懂Python的存根文件和类型检查)

    参考资料: https://blog.csdn.net/weixin_40908748/article/details/106252884 https://www.python.org/dev/pep ...

  4. RAC上的DG搭建

    准备工作 修改rman_backup这个文件的所有者和所属组,修改为oracle用户的oinstall组的文件 #chown –R oracle:oinstall /rman_backup/ 主库和备 ...

  5. 【Jboss】一台服务器上如何部署多个jboss

    一台服务器上如何部署多个jboss呢?直接把整个部署环境copy一份到相应的目录下? 这样只是前提,但是启动复制后的jboss就会发现,有很多端口被占用 3873,8080,8009,8443,808 ...

  6. kubernets之卷

    一 卷的由来以及种类和常用的卷的类型 前面介绍了大部分都是pod的管理以及在集群内部和集群外部如何访问pod,但是我们也了解到,pod是有生命周期的,当pod所在节点下线,或者等其他原因原因导致pod ...

  7. P1140 相似基因(字符串距离,递推)

    题目链接: https://www.luogu.org/problemnew/show/P1140 题目背景 大家都知道,基因可以看作一个碱基对序列.它包含了44种核苷酸,简记作A,C,G,TA,C, ...

  8. Oracle备份审计表SYS.AUD$和SYS.FGA_LOG$

    ORACLE的审计表不可以使用expdp和impdp导出和导入,如果使用,会报如下错误: 需要使用exp和imp进行导出和导出 导出语句: exp " '/ as sysdba' " ...

  9. IE浏览器直接在页面中显示7z文件而不是下载问题解决

    IE浏览器中输入7z文件的完整下载URL后,不是保存文件,而是直接在页面中显示(当然是乱码) 这是因为浏览器对不同的资源文件处理的方式不同,例如图片文件,一般会直接打开,所以我们可以不用7z,使用zi ...

  10. 在Ubuntu18.04下编译出ffmpeg(支持推流H265成rtmp)

    Ubuntu18.04下编译libx264.libx265.libfdk_aac和ffmpeg 一.编译x264库 二.编译fdk-aac库 三.编译x265库 四.编译FFmpeg源码 五.设置环境 ...