zoukankan      html  css  js  c++  java
  • [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
    ");
    68                 continue;
    69             }
    70             if (query(T,y,1e9)<k)printf("Yes
    ");
    71             else printf("No
    ");
    72         }
    73     }
    74 }
    View Code
  • 相关阅读:
    php7.4 降级 php7.1 的坑
    python 记录网页 生成pdf
    Mac 安装常用软件环境
    python 2.7 操作 excel
    007整数反转
    006Z字形变换
    005最长回文子串
    004寻找两个正序数组的中位数
    003无重复字符的最长子串
    002两数相加
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13334485.html
Copyright © 2011-2022 走看看