0%

2024 CCPC Liaoning Provincial Contest——G. 顾影自怜(线段树上二分)

思路讲解

线段树上二分,其实还是挺简单的,跑的也比较快。

然后也不用很固执的不用递归,zkw确实好,但是递归的线段树上二分更好理解,跑的也比较快。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 找到最靠近r的符合位置
template<class F> int findl(int r,F&&fun){
return findl(1,r,0,sz-1,fun);
}
// 找到最靠近r的符合位置
template<class F> int findl(int o,int qr,int l,int r,F&&fun){
if(l==r){
return l;
}
// pushdown(o);
ll ls=o<<1,rs=ls|1;
ll mid=l+r>>1;
ll pos=-1;
if(fun(tr[rs]) && mid+1<=qr) pos=findl(rs,qr,mid+1,r,fun);
if(pos!=-1) return pos;
if(fun(tr[ls])) pos=findl(ls,qr,l,mid,fun);
return pos;
}
// 找最靠近l的符合位置
template<class F> int findr(int l,F&&fun){
return findr(1,l,0,sz-1,fun);
}
// 找最靠近l的符合位置
template<class F> int findr(int o,int ql,int l,int r,F&&fun){
if(l==r){
return l;
}
// pushdown(o);
ll ls=o<<1,rs=ls|1;
ll mid=l+r>>1;
ll pos=-1;
if(fun(tr[ls]) && mid>=ql) pos=findr(ls,ql,l,mid,fun);
if(pos!=-1) return pos;
if(fun(tr[rs])) pos=findr(rs,ql,mid+1,r,fun);
return pos;
}

AC代码

https://qoj.ac/submission/1263129

心路历程(WA,TLE,MLE……)