[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,那么就需要根据个数来查询)
View Code
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 }