题目:
题目描述
小林和亮亮来到森林中探险, 森林中有一条长度为 S 的小路 (编号从 1 到 S) , 且在小路上时常会起雾,亮亮也可以用神光让雾消散。 小林则关心在某一位置的视野。若位置 x 有浓雾,则位置 x 的视野为 0。若 从 x 一直到 S 或从 x 一直到 1 全都没有浓雾,则视野为INF。其他情况下,位置x的视野为maxR−L+1maxR−L+1 要满足这个区间内没有浓雾的产生. 具体来说,会有以下事件发生: 1、“1 L R”小路的[L, R]部分产生了浓雾; 2、“2 L R”小路的[L, R]部分浓雾散去了。 3、“3 X” 查询 X 点的视野。 一开始,小路上没有任何浓雾。
输入输出格式
输入格式:
第一行一个整数,为小路的长度 S。 第二行一个整数,为事件数 Q。 接下来 Q 行,每行一个事件,格式如题目描述。
输出格式:
对于每一个询问事件,输出一个整数或一行字符串“INF”,代表所求视野。
输入输出样例
输入样例#1:
5
5
1 2 4
3 1
3 4
2 3 3
3 3
输出样例#1:
INF
0
1
说明
对于 40%的数据,SQ <= 510^7。
对于 100%的数据,2≤S≤100,000,2≤Q≤200,000,1≤L≤R≤S,1≤X≤S。
思路:线段树。
代码:
#include<bits/stdc++.h>
using namespace std;
#define lson (o*2)
#define rson (o*2+1)
#define mid (l+r)/2
#define maxn 100000
#define read(x) scanf("%d",&x)
struct Node{
int L,R;
int x,lzy;
int xl,xr;
int lsz,rsz;
};
int n,m;
int P,Q;
Node a[maxn*10];
void push_up(int o) {
if(a[lson].x>a[rson].x) {
a[o].x=a[lson].x;
a[o].xl=a[lson].xl,a[o].xr=a[lson].xr;
} else {
a[o].x=a[rson].x;
a[o].xl=a[rson].xl,a[o].xr=a[rson].xr;
}
if(a[lson].rsz+a[rson].lsz>a[o].x) {
a[o].x=a[lson].rsz+a[rson].lsz;
a[o].xl=a[lson].R-a[lson].rsz+1,a[o].xr=a[rson].L+a[rson].lsz-1;
}
a[o].lsz=a[lson].lsz,a[o].rsz=a[rson].rsz;
if(a[lson].lsz==a[lson].R-a[lson].L+1) a[o].lsz=a[lson].lsz+a[rson].lsz;
if(a[rson].rsz==a[rson].R-a[rson].L+1) a[o].rsz=a[rson].rsz+a[lson].rsz;
}
void push_down(int o) {
if(a[o].lzy==0) {
a[lson].x=a[lson].lsz=a[lson].rsz=a[lson].R-a[lson].L+1;
a[rson].x=a[rson].lsz=a[rson].rsz=a[rson].R-a[rson].L+1;
a[lson].lzy=a[rson].lzy=0;
a[lson].xl=a[lson].L,a[lson].xr=a[lson].R;
a[rson].xl=a[rson].L,a[rson].xr=a[rson].R;
a[o].lzy=-1;
} else if(a[o].lzy==1) {
a[lson].x=a[lson].lsz=a[lson].rsz=0;
a[rson].x=a[rson].lsz=a[rson].rsz=0;
a[lson].lzy=a[rson].lzy=1;
a[lson].xl=a[lson].L,a[lson].xr=a[lson].R;
a[rson].xl=a[rson].L,a[rson].xr=a[rson].R;
a[o].lzy=-1;
}
}
void build(int o,int l,int r) {
a[o].L=a[o].xl=l,a[o].R=a[o].xr=r;
a[o].lzy=-1;a[o].x=a[o].lsz=a[o].rsz=r-l+1;
if(l==r) return ;
build(lson,l,mid),build(rson,mid+1,r);
}
void update(int o,int l,int r,int d) {
push_down(o);
if(l>Q||r<P) return ;
if(l>=P&&r<=Q) {
a[o].lzy=d;
if(d==0) a[o].x=a[o].lsz=a[o].rsz=a[o].R-a[o].L+1;
else a[o].x=a[o].lsz=a[o].rsz=0;
a[o].xl=l,a[o].xr=r;
return ;
}
update(lson,l,mid,d),update(rson,mid+1,r,d);
push_up(o);
}
int query(int o,int l,int r) {
push_down(o);
if(l>P||r<P) return 0;
if(a[o].xl<=P&&a[o].xr>=P) return a[o].x;
int x=max(query(lson,l,mid),query(rson,mid+1,r));
int L=a[lson].R-a[lson].rsz+1,R=a[rson].L+a[rson].lsz-1;
if(L<=P&&R>=P) x=max(x,R-L+1);
return x;
}
int main() {
read(n),read(m);
build(1,1,n);
while(m--) {
int opr;
read(opr);
if(opr==1) {
read(P),read(Q);
update(1,1,n,1);
} else if(opr==2) {
read(P),read(Q);
update(1,1,n,0);
} else {
read(P);int PP=P;
int ans=query(1,1,n);
int x1,xn;
P=1,x1=query(1,1,n);
P=n,xn=query(1,1,n);
if(x1>=PP||PP+xn>n) printf("INF\n");
else printf("%d\n",ans);
}
}
return 0;
}
578

被折叠的 条评论
为什么被折叠?



