【线段树|191024省选测试题解】T1:有n个不相交矩形障碍,求从原点走到某个目标点的最短路,目标点在x轴上
显然矩形的右端点是没用的,我们保留左边即可
显然不会往左走,dp一下是 n 2 n^2 n2的,用扫描线优化一下即可
#include
#define pb push_back
#define ll long long
using namespace std;
inline int read(){
int res=0,f=1;
char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-f;
ch=getchar();
}
while(isdigit(ch)) {res=(res<<1)+(res<<3)+(ch^48);
ch=getchar();
}
return res*f;
}
const int N=5e5+5,INF=1e9;
inline int D(int x1,int y1,int x2,int y2){return abs(x1-x2)+abs(y1-y2);
}
int n,aim;
struct sqr{
int lx,rx,ly,ry;
inline bool operator < (const sqr &rhs)const{return lxs;
int main(){
n=read();
aim=read();
for(int i=1;
i<=n;
i++){
int lx=read(),ly=read(),rx=read(),ry=read();
if(lx>rx) swap(lx,rx);
if(ly>ry) swap(ly,ry);
p[i].lx=lx,p[i].rx=rx,p[i].ly=ly,p[i].ry=ry;
}
s.insert(info(0,0,0));
sort(p+1,p+n+1);
for(int i=1;
i<=n;
i++){
set::iterator l=s.lower_bound(info(0,p[i].ly,0));
set::iterator r=s.upper_bound(info(0,p[i].ry,0));
int L=INF,R=INF;
while(l!=r){
L=min(L,l->dis+D(p[i].lx,p[i].ry,l->x,l->y));
R=min(R,l->dis+D(p[i].lx,p[i].ly,l->x,l->y));
s.erase(l++);
}
s.insert(info(p[i].lx,p[i].ry,L));
s.insert(info(p[i].lx,p[i].ly,R));
}
int ans=INF;
for(set::iterator it=s.begin();
it!=s.end();
it++) ans=min(ans,it->dis+D(aim,0,it->x,it->y));
cout<
T2:LOJ火锅盛宴
一个优先队列维护没熟的,一个线段树维护熟的,然后模拟就完了
#include
#define pii pair
#define pb push_back
#define mp make_pair
#define ll long long
#define fi first
#define se second
#define db double
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
char ch=nc();
int sum=0;
while(!(ch>='0'&&ch<='9'))ch=nc();
while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
return sum;
}
struct info{
int x,id;
info(){}
info(int _x,int _id):x(_x),id(_id){}
inline bool operator > (const info &rhs)const{return x>rhs.x;
}
};
int n;
const int N=1e5+5;
namespace segtree{
struct seg{int l,r,sum;
}tr[N<<2];
#define ls tr[k].l
#define rs tr[k].r
#define mid (ls+rs>>1)
inline void build(int k,int l,int r){
ls=l;
rs=r;
tr[k].sum=0;
if(l==r) return;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
}
inline void modify(int k,int pos){//op 0
++tr[k].sum;
if(ls==rs) return;
if(pos<=mid) modify(k<<1,pos);
else modify(k<<1|1,pos);
}
inline int query_min(int k){//op 1
if(!tr[k].sum) return 0;
--tr[k].sum;
if(ls==rs) return ls;
if(tr[k<<1].sum) return query_min(k<<1);
else return query_min(k<<1|1);
}
inline int query_pos(int k,int pos){//op 2
if(!tr[k].sum) return 0;
if(ls==rs){--tr[k].sum;
return 1;
}
int res=0;
if(pos<=mid) res=query_pos(k<<1,pos);
else res=query_pos(k<<1|1,pos);
tr[k].sum-=res;
return res;
}
inline int query_seq(int k,int ql,int qr){ //op 3
if(ql>rs || qrmid) return query_seq(k<<1|1,ql,qr);
else return query_seq(k<<1,ql,mid)+query_seq(k<<1|1,mid+1,qr);
}
}
using namespace segtree;
int w[N];
priority_queue,greater >q;
dequeson[N];
inline void file(){freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
}
int main(){
int t=read();
while(t--){
n=read();
build(1,1,n);
for(int i=1;
i<=n;
i++) w[i]=read(),son[i].clear();
while(!q.empty()) q.pop();
int Q=read();
while(Q--){
int t=read(),op=read();
while(q.size() && q.top().x<=t){
int y=q.top().id;
modify(1,y);
son[y].pop_front();
q.pop();
}
if(op==0){
int x=read();
son[x].push_back(t+w[x]);
q.push(info(t+w[x],x));
}
else if(op==1){
if(!tr[1].sum) puts("Yazid is angry.");
else cout<dp[1]) dp[1]=h[y];
}
ans=max(ans,val+1);
ans=max(ans,dp[0]+val+1);
ans=max(ans,dp[0]+dp[1]+val+1);
for(int i=head[v];
i;
i=nxt[i]){
int y=vis[i];
if(y==fa) continue;
if(h[y]!=dp[0]) dfs2(y,v,max(val,dp[0])+1);
else dfs2(y,v,max(val,dp[1])+1);
}
}
int main(){
n=read();
for(int i=0;
i
推荐阅读
- 线段树|[类欧几里得算法 线段树] BZOJ 1938 [CROATIAN2010] ALADIN
- 牛客 C. 子段乘积(线段树)
- 牛客挑战赛39 C 牛牛的等差数列(线段树)(*)
- 牛客 数据结构(区间修改+求区间元素平方和)
- 校门外的树 线段树版
- 树形dp|Codeforces 917D Stranger Trees 树形dp+容斥原理
- Codeforces Round #275 (Div. 1)D(树形DP)
- Codeforces Round #277 (Div. 2)D(树形DP计数类)
- 树链剖分|牛客练习赛51 F-ABCBA(树链剖分,线段树,状态转移)
- 数论|bzoj 1938 - 类欧几里得+线段树