Luck and Love
世界上上最远的距离不是相隔天涯海角
而是我在你面前
可你却不知道我爱你
―― 张小娴
前段日子,枫冰叶子给Wiskey做了个征婚启事,聘礼达到500万哦,天哪,可是天文数字了啊,不知多少MM蜂拥而至,顿时万人空巷,连扫地的大妈都来凑热闹来了。―_―|||
由于人数太多,Wiskey实在忙不过来,就把统计的事情全交给了枫冰叶子,自己跑回家休息去了。这可够枫冰叶子忙的了,他要处理的有两类事情,一是得接受MM的报名,二是要帮Wiskey查找符合要求的MM中缘分最高值。
Input
本题有多个测试数据,第一个数字M,表示接下来有连续的M个操作,当M=0时处理中止。
接下来是一个操作符C。
当操作符为‘I’时,表示有一个MM报名,后面接着一个整数,H表示身高,两个浮点数,A表示活泼度,L表示缘分值。 (100<=H<=200, 0.0<=A,L<=100.0)
当操作符为‘Q’时,后面接着四个浮点数,H1,H2表示身高区间,A1,A2表示活泼度区间,输出符合身高和活泼度要求的MM中的缘分最高值。 (100<=H1,H2<=200, 0.0<=A1,A2<=100.0)
所有输入的浮点数,均只有一位小数。
Output
对于每一次询问操作,在一行里面输出缘分最高值,保留一位小数。
对查找不到的询问,输出-1。
Sample Input
8
I 160 50.5 60.0
I 165 30.0 80.5
I 166 10.0 50.0
I 170 80.5 77.5
Q 150 166 10.0 60.0
Q 166 177 10.0 50.0
I 166 40.0 99.9
Q 166 177 10.0 50.0
0
Sample Output
80.5
50.0
99.9
先分享坑点:坑点1:给出的H,A是可以重复的,所以update时取max, 坑点2:查询的时候给出的 H1,H2,A1,A2不一定满足 H1 <= H1 && A1 <= A2.,坑点3:如果用double开数组然后离散,可能会有精度问题,这里我使用 double读入然后 *10 转为int
首先上四叉树的吧。四叉树我一开始一直MLE,然后搜了一下题解,题解都是开的 [5000][5000 << 2] 的空间,但是能过,表示很懵。。然后在队友的帮助下,debug出来发现是递归太深了,最后改出了bug,但是还是不明白为什么。。有大佬可以解答一下。
先贴上有bug的一部分代码:。。请看以下代码。
void update(int xl,int xr,int yl,int yr,int posx,int posy,int i,short val,int dep){
if(xl > xr || yl > yr) return ;
if(xl == xr && yl == yr){ /// 若此if语句该成 if(xl == xr && yl == yr && xl == posx && yl == posy) 便递归爆栈了,原因不明
maxx[i] = max(maxx[i],val);
return ;
}
int midx = (xl + xr) >> 1,midy = (yl + yr) >> 1;
if(posx <= midx && posy <= midy) update(xl,midx,yl,midy,posx,posy,son(0),val,dep + 1);
else if(posx <= midx && posy > midy) update(xl,midx,midy + 1,yr,posx,posy,son(1),val,dep + 1);
else if(posx > midx && posy <= midy) update(midx + 1,xr,yl,midy,posx,posy,son(2),val,dep + 1);
else if(posx > midx && posy > midy) update(midx + 1,xr,midy + 1,yr,posx,posy,son(3),val,dep + 1);
push_up(xl,xr,yl,yr,i);
}
四叉树AC代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define clr(a,b) memset((a),b,sizeof(a))
using namespace std;
#define son(x) (i * 4 - 2 + x)
const int M = 210;
const int maxn = 1000 * 5000 * 1.5;
short maxx[maxn];
void push_up(int xl,int xr,int yl,int yr,int i){
maxx[i] = maxx[son(0)];
if(yl < yr) maxx[i] = max(maxx[i],maxx[son(1)]);
if(xl < xr) maxx[i] = max(maxx[i],maxx[son(2)]);
if(xl < xr && yl < yr)
maxx[i] = max(maxx[i],maxx[son(3)]);
}
void update(int xl,int xr,int yl,int yr,int posx,int posy,int i,short val,int dep){
if(xl > xr || yl > yr) return ;
if(xl == xr && yl == yr){
maxx[i] = max(maxx[i],val);
return ;
}
int midx = (xl + xr) >> 1,midy = (yl + yr) >> 1;
if(posx <= midx && posy <= midy) update(xl,midx,yl,midy,posx,posy,son(0),val,dep + 1);
else if(posx <= midx && posy > midy) update(xl,midx,midy + 1,yr,posx,posy,son(1),val,dep + 1);
else if(posx > midx && posy <= midy) update(midx + 1,xr,yl,midy,posx,posy,son(2),val,dep + 1);
else if(posx > midx && posy > midy) update(midx + 1,xr,midy + 1,yr,posx,posy,son(3),val,dep + 1);
push_up(xl,xr,yl,yr,i);
}
short query(int xl,int xr,int yl,int yr,int qxl,int qxr,int qyl,int qyr,int i,int dep){
if(xl > xr || yl > yr)
return -1;
if(xl > qxr || qxl > xr || yl > qyr || qyl > yr)
return -1;
if(qxl <= xl && xr <= qxr && qyl <= yl && yr <= qyr)
return maxx[i];
int midx = (xl + xr) >> 1,midy = (yl + yr) >> 1;
short ans = -1;
if(qxl <= midx && qyl <= midy)
ans = max(ans,query(xl,midx,yl,midy,qxl,qxr,qyl,qyr,son(0),dep + 1));
if(qxl <= midx && qyr > midy)
ans = max(ans,query(xl,midx,midy + 1,yr,qxl,qxr,qyl,qyr,son(1),dep + 1));
if(qxr > midx && qyl <= midy)
ans = max(ans,query(midx + 1,xr,yl,midy,qxl,qxr,qyl,qyr,son(2),dep + 1));
if(qxr > midx && qyr > midy)
ans = max(ans,query(midx + 1,xr,midy + 1,yr,qxl,qxr,qyl,qyr,son(3),dep + 1));
return ans;
}
int main() {
int m;
double tttt,qqqq;
int H,A,A1,A2,H1,H2;
short L,ans;
while(~scanf("%d",&m) && m){
clr(maxx,-0x3f);
for(int i = 1;i <= m;++ i){
char op; scanf(" %c",&op);
if(op == 'I'){
scanf("%d%lf%lf",&H,&tttt,&qqqq);
A = (int)(tttt * 10);
L = (short)(qqqq * 10);
update(1,200,1,1000,H,A,1,L,0);
}
else {
scanf("%d%d%lf%lf",&H1,&H2,&tttt,&qqqq);
if(H1 > H2) swap(H1,H2);
A1 = (int)(tttt * 10);
A2 = (int)(qqqq * 10);
if(A1 > A2) swap(A1,A2);
ans = query(1,200,1,1000,H1,H2,A1,A2,1,0);
if(ans == -1)
printf("-1\n");
else printf("%.1f\n",(double)ans * 1.0 / 10);
}
}
}
return 0;
}
然后就是树套树,树套树得注意 update 的部分,即
!!! subupdate含 f 标志
void subupdate(int yl,int yr,int posy,int fa_i,int i,int val,int f){
if(yl == yr){
if(f) maxx[fa_i][i] = max(maxx[fa_i][i],val); ///满足 f 是更新val
else maxx[fa_i][i] = max(maxx[fa_i << 1][i],maxx[fa_i << 1 | 1][i]); ///否则是push_up。而且push_up的是x轴的
}
else {
int mid = (yl + yr) >> 1;
if(posy <= mid) subupdate(yl,mid,posy,fa_i,ls,val,f);
if(posy > mid) subupdate(mid + 1,yr,posy,fa_i,rs,val,f);
maxx[fa_i][i] = max(maxx[fa_i][ls],maxx[fa_i][rs]);
}
}
void update(int xl,int xr,int yl,int yr,int posx,int posy,int i,int val){
if(xl == xr){
subupdate(yl,yr,posy,i,1,val,1); ///!!! 此处f == 1
return ;
}
int mid = (xl + xr) >> 1;
if(posx <= mid) update(xl,mid,yl,yr,posx,posy,ls,val);
if(posx > mid) update(mid + 1,xr,yl,yr,posx,posy,rs,val);
subupdate(yl,yr,posy,i,1,val,0); ///!!! 此处 f == 0
}
树套树AC代码:
#include<bits/stdc++.h>
#define debug(x) cout << "[" << #x <<": " << (x) <<"]"<< endl
#define pii pair<int,int>
#define clr(a,b) memset((a),b,sizeof(a))
#define rep(i,a,b) for(int i = a;i < b;i ++)
#define pb push_back
#define MP make_pair
#define LL long long
#define ull unsigned LL
#define ls i << 1
#define rs (i << 1) + 1
#define INT(t) int t; scanf("%d",&t)
using namespace std;
const int maxn = 1010;
const int inf = 0x3f3f3f3f;
int maxx[800][4000];
void subupdate(int yl,int yr,int posy,int fa_i,int i,int val,int f){
if(yl == yr){
if(f) maxx[fa_i][i] = max(maxx[fa_i][i],val);
else maxx[fa_i][i] = max(maxx[fa_i << 1][i],maxx[fa_i << 1 | 1][i]);
}
else {
int mid = (yl + yr) >> 1;
if(posy <= mid) subupdate(yl,mid,posy,fa_i,ls,val,f);
if(posy > mid) subupdate(mid + 1,yr,posy,fa_i,rs,val,f);
maxx[fa_i][i] = max(maxx[fa_i][ls],maxx[fa_i][rs]);
}
}
void update(int xl,int xr,int yl,int yr,int posx,int posy,int i,int val){
if(xl == xr){
subupdate(yl,yr,posy,i,1,val,1);
return ;
}
int mid = (xl + xr) >> 1;
if(posx <= mid) update(xl,mid,yl,yr,posx,posy,ls,val);
if(posx > mid) update(mid + 1,xr,yl,yr,posx,posy,rs,val);
subupdate(yl,yr,posy,i,1,val,0);
}
int subquery(int yl,int yr,int qyl,int qyr,int fa_i,int i){
if(qyl <= yl && yr <= qyr){
return maxx[fa_i][i];
}
int ans = -1;
int mid = (yl + yr) >> 1;
if(qyl <= mid)
ans = max(ans,subquery(yl,mid,qyl,qyr,fa_i,ls));
if(qyr > mid)
ans = max(ans,subquery(mid + 1,yr,qyl,qyr,fa_i,rs));
return ans;
}
int query(int xl,int xr,int yl,int yr,int qxl,int qxr,int qyl,int qyr,int i){
if(qxl <= xl && xr <= qxr){
return subquery(yl,yr,qyl,qyr,i,1);
}
int ans = -1;
int mid = (xl + xr) >> 1;
if(qxl <= mid)
ans = max(ans,query(xl,mid,yl,yr,qxl,qxr,qyl,qyr,ls));
if(qxr > mid)
ans = max(ans,query(mid + 1,xr,yl,yr,qxl,qxr,qyl,qyr,rs));
return ans;
}
int main() {
int m;
double tttt,qqqq;
int H,A,A1,A2,H1,H2;
int L,ans;
while(~scanf("%d",&m) && m){
clr(maxx,-0x3f);
for(int i = 1;i <= m;++ i){
char op; scanf(" %c",&op);
if(op == 'I'){
scanf("%d%lf%lf",&H,&tttt,&qqqq);
A = (int)(tttt * 10);
L = (int)(qqqq * 10);
update(1,200,1,1000,H,A,1,L);
}
else {
scanf("%d%d%lf%lf",&H1,&H2,&tttt,&qqqq);
if(H1 > H2) swap(H1,H2);
A1 = (int)(tttt * 10);
A2 = (int)(qqqq * 10);
if(A1 > A2) swap(A1,A2);
ans = query(1,200,1,1000,H1,H2,A1,A2,1);
if(ans == -1)
printf("-1\n");
else printf("%.1f\n",(double)ans * 1.0 / 10);
}
}
}
return 0;
}