[nowcoder5667H]Happy Triangle

可以发现合法的答案有两种可能:
1.询问的$x$即为最大值(或之一),那么只需要找到x前两个数并判断即可
2.询问的$x$不是最大值,那么就要保证另外两边之差小于$x$,维护后缀中$的前驱k-k的前驱$最小的数即可,可以使用线段树
然而这道题还有很多的细节:
1.这里的前驱可以与k相等(因为$x,k,k$($k>x$)也可以),因此在插入后从1变成2同样也要修改(同理删除2变成1)
2.但修改时找前驱需要找到第一个比他小的,然后它的后继同样也要修改
3.$x$的前两个数有三种可能:$x,x,x$、$x,x,y$、$x,y,z$,需要分类讨论(比如有1个x,那么就需要根据个数来查询)
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 200005
 4 #define oo 0x3f3f3f3f
 5 #define mid (l+r>>1)
 6 #define T r,1,1e9
 7 int V,r,n,p,k,ls[N*30],rs[N*30],sum[N*30],f[N*30];
 8 int add(int &k,int l,int r,int x,int y){
 9     if (!k)k=++V;
10     sum[k]+=y;
11     if (l==r)return sum[k];
12     if (x<=mid)return add(ls[k],l,mid,x,y);
13     return add(rs[k],mid+1,r,x,y);
14 }
15 int find1(int k,int l,int r,int x){
16     if ((!x)||(!sum[k]))return -oo;
17     if (l==r)return l;
18     if (x<=mid)return find1(ls[k],l,mid,x);
19     int ans=find1(rs[k],mid+1,r,x);
20     if ((ans>0)||(!sum[ls[k]]))return ans;
21     return find1(ls[k],l,mid,x);
22 }
23 int find2(int k,int l,int r,int x){
24     if ((x>1e9)||(!sum[k]))return oo;
25     if (l==r)return l;
26     if (mid<x)return find2(rs[k],mid+1,r,x);
27     int ans=find2(ls[k],l,mid,x);
28     if ((ans!=oo)||(!sum[rs[k]]))return ans;
29     return find2(rs[k],mid+1,r,x);
30 }
31 void update(int k,int l,int r,int x,int y){
32     if (l==r){
33         f[k]=y;
34         return;
35     }
36     if (x<=mid)update(ls[k],l,mid,x,y);
37     else update(rs[k],mid+1,r,x,y);
38     f[k]=min(f[ls[k]],f[rs[k]]);
39 }
40 int query(int k,int l,int r,int x,int y){
41     if ((!k)||(l>y)||(x>r))return oo;
42     if ((x<=l)&&(r<=y))return f[k];
43     return min(query(ls[k],l,mid,x,y),query(rs[k],mid+1,r,x,y));
44 }
45 int main(){
46     scanf("%d",&n);
47     memset(f,oo,sizeof(f));
48     for(int i=1;i<=n;i++){
49         scanf("%d%d",&p,&k);
50         int x=find1(T,k-1),y=find2(T,k+1);
51         if (p<3){
52             int t=add(T,k,3-2*p);
53             if ((p==1)&&(t==2))update(T,k,0);
54             if ((p==2)&&(t==1))update(T,k,k-x);
55             if ((p==1)&&(t==1)){
56                 update(T,k,k-x);
57                 if ((y!=oo)&&(add(T,y,0)==1))update(T,y,y-k);
58             }
59             if ((p==2)&&(t==0)){
60                 update(T,k,oo);
61                 if ((y!=oo)&&(add(T,y,0)==1))update(T,y,y-x);
62             }
63         }
64         else{
65             int t=add(T,k,0);
66             if ((t>1)||((x>0)&&((t==1)||(2*x-query(T,x,x)>k)))){
67                 printf("Yes\n");
68                 continue;
69             }
70             if (query(T,y,1e9)<k)printf("Yes\n");
71             else printf("No\n");
72         }
73     }
74 }
View Code

 

posted @ 2020-07-18 08:47  PYWBKTDA  阅读(183)  评论(0编辑  收藏  举报