毯子 题解(COCI 2008-2009Final C)
来源:互联网 发布:淘宝计划书范文 编辑:程序博客网 时间:2024/06/02 19:41
[题意]
N 块矩形毯子铺在地上。0秒时(0,0)处有一桶油倒了,然后开始流呀流,每秒往八个方向扩散一个单位。注意,这里的坐标描述一个单元格,不表示点。M个询问,每次问一个时间点被油染到的毯子面积(若有毯子重叠,面积也要累加,如一个单位格被三个毯子覆盖,那么被油染到之后就算3个单位面积)。
[思路]
50分:暴力!n*m枚举每个询问时每块毯子被染到的范围.直接把顶点算出.
100分:
有两个切入点:
1)每块毯子被染的区域增量随时间改变是有规律的:
可以分成两个部分:
第一部分是一个公差为2的等差数列:如图所示,增量分别是3,5,7块;
第二部分是一个常数列:图中的常数为3.
每个部分都是一个独立的区间.
2)每块毯子染到的面积是独立的,可以叠加.
确定了以上的两点, 就可以联想到刷漆.把每个时间点的状态叠加.
每个时间点的状态由两个变量来表示:b,k.b表示当前时间点的染到的面积增量的值,k表示当前时间点染到的面积增量的公差.
对于每个时间点t对t-1的增量就可以表示为:b+k+b[t](b[t],表示t时间点的面积增量)
优化:
因为油的变化趋势是随原点对称的,所以把所有矩形都翻到右上角去,
可以在刷漆时更简便.
注意:
1. 输入数据有负数,慎用读入挂
2. 在翻折矩形之后,矩形的个数增加了,数组比忘了开大点!!
[启发]
1. 对于询问类的问题可以离线做.
2. 随时间增长的变量可以找规律,挖性质.
<span style="font-family:Comic Sans MS;font-size:18px;">#include<cstdio>#include<iostream>#include<algorithm>#include<vector>#include<map>#define ll long longusing namespace std;inline void rd(int &res){ res=0; int k=1;char c; while(c=getchar(),c<48&&c!='-'); if(c=='-'){k=-1;c=getchar();} do{ res=(res<<1)+(res<<3)+(c^48); }while(c=getchar(),c>=48); res*=k;}inline void print(ll k){ if(k==0)return ; print(k/10); putchar((k%10)^48);}inline void sc(ll k){ print(k); if(k==0)putchar('0'); putchar('\n');}const int M=100005;const int N=1e6+5;struct node{int x1,y1,x2,y2;}A[M*4],B[M*4];int n,m;ll res[N];struct LAY{ll b,k;};vector<LAY>brush[N];void add(int t,ll b,ll k){//b表示常量,k表示增量 brush[t].push_back((LAY){b,k});}void solve(){ int i,j,k,tot=0,now=n; for(i=1;i<=now;i++){//矩形反转 int x1=A[i].x1,x2=A[i].x2,y1=A[i].y1,y2=A[i].y2; if(x1>=0&&x2>=0&&y1>=0&&y2>=0){ B[++tot]=(node){x1,y1,x2,y2};continue; } if(x1<0){ if(x2<0) A[++now]=(node){-x2,y1,-x1,y2}; else { A[++now]=(node){1,y1,-x1,y2};//分成两块 A[++now]=(node){0,y1,x2,y2}; } continue; } else if(x1>=0&&x2>=0&&y1<0){ if(y2<0)B[++tot]=(node){x1,-y2,x2,-y1}; else { B[++tot]=(node){x1,0,x2,y2}; B[++tot]=(node){x1,1,x2,-y1}; } } } for(i=1;i<=tot;i++){ int x1=B[i].x1,x2=B[i].x2,y1=B[i].y1,y2=B[i].y2; int t1,t2,t3; ll s1,s2; t1=max(x1,y1); t2=min(x2,y2); t3=max(x2,y2);//算出两个部分分别的时间点 s1=1ll*(min(x2,t1)-max(x1,0)+1)*(min(y2,t1)-max(y1,0)+1); if(x2>y2)s2=y2-y1+1; else s2=x2-x1+1; if(t2<t1)t2=t1; add(t1,s1,2);//刷漆:第一部分初始值为s1,公差为2 add(t2+1,-s1-1ll*(t2-t1+1)*2,-2);//结束时把第一部分增加的值减去 add(t2+1,s2,0);//常量部分 add(t3+1,-s2,0); } ll b=0,plus=0,ans=0; for(i=0;i<N;i++){ b+=plus;//公差 for(j=0;j<brush[i].size();j++){ b+=brush[i][j].b;plus+=brush[i][j].k;//刷漆累加 } ans+=b; res[i]=ans; }}int main(){ rd(n); int t; for(int i=1;i<=n;i++){ rd(A[i].x1);rd(A[i].y1); rd(A[i].x2);rd(A[i].y2); } solve(); rd(m); for(int i=1;i<=m;i++){ rd(t); sc(res[t]); } return 0;}20160625离线赛/COCI 2008-2009FinalC
1 0
- 毯子 题解(COCI 2008-2009Final C)
- BZOJ2223 [Coci 2009]PATULJCI 题解&代码
- 【BZOJ】【P2223】【Coci 2009】【PATULJCI】【题解】【整体二分】
- 【COCI 2009】ALADIN
- [BZOJ2223][Coci 2009]PATULJCI
- bzoj2223[Coci 2009] PATULJCI
- bzoj2223 [Coci 2009]PATULJCI
- bzoj 2223: [Coci 2009]PATULJCI
- BZOJ 2223: [Coci 2009]PATULJCI
- BZOJ 2223: [Coci 2009]PATULJCI
- 【COCI 2015/2016 #7】PROZOR(加强版) 题解
- 【COCI】 2271 邮递员 暴力(不是树形DP)题解 c++
- COCI 2016/2017 Round 4 C dp
- CodeFestival 2017 Final 题解
- bzoj2223: [Coci 2009]PATULJCI 主席树
- BZOJ2223: [Coci 2009]PATULJCI&&BZOJ3524: [Poi2014]Couriers
- [BZOJ3524] [Poi2014]Couriers/[BZOJ2223] [Coci 2009]PATULJCI
- [分块 随机化] BZOJ 2223 [Coci 2009]PATULJCI
- 从内存四区的角度理解指针
- ajax
- APP开发实战68-IntentService
- 【高性能 JavaScript --笔记】JavaScript 加载与执行
- Android requires compiler compliance level 5.0 or 6.0. Found '1.7' instead. Please use Android Tools
- 毯子 题解(COCI 2008-2009Final C)
- gen_event
- Mato的文件管理
- Machine Learning Foundations: A Case Study Approach-Regression-Assignment: Predicting House Prices
- matlab-高数 二元函数的泰勒展开
- 1002. A+B for Polynomials
- APP开发实战69-前台服务
- 备忘录模式(Memento)
- matlab-高数 二重积分(四限皆数)