zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营(第二场)[Happy Triangle]

    2020牛客暑期多校训练营(第二场)Happy Triangle

    题目大意:

    给你m次操作,每次操作两个数,(opt)(x)(opt) 有三种取值情况,

    • (opt==1) 表示把 (x) 放入数组
    • (opt==2) 表示把 (x) 移除
    • (opt==3) 表示查询 (x) 是不是数组中存在 $ a 、 b$ 使得 (x、a、b) 可以构成一个三角形

    题解:

    题目不是很难想,但是写起来感觉还是比较复杂的。。。

    第一第二个很好用线段树维护,第三个线段树就要维护一段区间的两个数的和最大和两个数的差最小。

    • 差最小,表示的是当前的 (x) 是最小值,所以要有解的话,就是最大值减去次大值要小于这个最小值即可,是要求后面的一段区间,所以在线段是位置 (i) 维护的是 (i) 到末尾的数字的差值最小。

      这个怎么维护呢,首先线段树+二分可以求出大于等于这个位置的最小值,求出来之后,直接用这个值 (val-x) 插入线段树位置 (i)

    • 然后就是和最大,表示的是当前的 (x) 是最大值,所以要有解,那么就是最大值要小于次大值+最小值,这个是要求前面一段区间,所以同理,线段树+二分求出前面一段区间的最大值,然后 (val+x) 插入线段树位置 (i)

    • 最后就是这个值是中间大小的值,那就是用前面的可以找到了。

    最后写的时候觉得用二分比较麻烦,于是就直接把这个值放入了线段树里面,直接线段树查询就可以了。

    总的来说,还是写的比较复杂的。。。

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define debug(x) printf("debug:%s=%d
    ",#x,x);
    //#define debug(x) cout << #x << ": " << x << endl
    using namespace std;
    const int maxn = 2e5+10;
    int mins[maxn*4],maxs[maxn*4],a[maxn],v[maxn],opt[maxn];
    int Min[maxn*4],Max[maxn*4],num[maxn*4],len;
    
    
    int MAX(int x,int y){
    	if(x&&y)  return v[x]>v[y]?x:y;
    	if(x) return x;
    	if(y) return y;
    	return 0;
    }
    
    int MIN(int x,int y){
    	if(x&&y) return v[x]>v[y]?y:x;
    	if(x) return x;
    	if(y) return y;
    	return 0;
    }
    
    void push_up(int id){
    //	debug("xxx");
        num[id]=max(num[id<<1],num[id<<1|1]);
        Min[id]=MIN(Min[id<<1],Min[id<<1|1]);
        Max[id]=MAX(Max[id<<1],Max[id<<1|1]);
    //    debug(id)
    //    debug(Min[id])
    //    debug(Max[id])
        mins[id]=min(mins[id<<1],mins[id<<1|1]);
        maxs[id]=max(maxs[id<<1],maxs[id<<1|1]);
    //    debug(mins[id]);
    //    debug(maxs[id]);
    //    debug(mins[id<<1]);
    //    debug(mins[id<<1|1]);
    }
    
    void update(int id,int l,int r,int pos,int f){
    //	printf("id=%d l=%d r=%d pos=%d
    ",id,l,r,pos);
        if(l==r){
            if(f) {
                if(!num[id]) Min[id]=l,Max[id]=l;
                num[id]++;
            }
            else{
                num[id]--;
                if(!num[id]) Min[id]=0,Max[id]=0;
            }
    //        debug("sss");
            return;
        }
        int mid=(l+r)>>1;
        if(pos<=mid) update(id<<1,l,mid,pos,f);
        else update(id<<1|1,mid+1,r,pos,f);
    //    debug(id)
        push_up(id);
    }
    
    int query_min(int id,int l,int r,int x,int y){
    //	printf("id = %d l=%d r=%d x=%d y=%d
    ",id,l,r,x,y);
        if(y<l||x>r) return 0;
        if(x<=l&&y>=r) {
    		return Min[id];
    	}
        int mid=(l+r)>>1,ans=0;
        if(x<=mid) ans=MIN(ans,query_min(id<<1,l,mid,x,y));
        if(y>mid) ans=MIN(ans,query_min(id<<1|1,mid+1,r,x,y));
        return ans;
    }
    
    int query_max(int id,int l,int r,int x,int y){
    //	printf("query_max id=%d l=%d r=%d x=%d y=%d
    ",id,l,r,x,y);
        if(y<l||x>r) return 0;
        if(x<=l&&y>=r) {
    //    	debug(Max[id])
        	return Max[id];
        }
        int mid=(l+r)>>1,ans=0;
        if(x<=mid) ans=MAX(ans,query_max(id<<1,l,mid,x,y));
        if(y>mid) ans=MAX(ans,query_max(id<<1|1,mid+1,r,x,y));
        return ans;
    }
    
    void modify_max(int id,int l,int r,int pos,int val,int f){
    //	printf("ss  id=%d l=%d r=%d pos=%d val=%d f=%d
    ",id,l,r,pos,val,f);
    	if(pos<l||pos>r) return ;
        if(l==r){
        	if(f) maxs[id]=max(maxs[id],val);
    		else maxs[id]=val;
    //		debug(maxs[id]);
            return  ;
        }
        int mid=(l+r)>>1;
        if(pos<=mid) modify_max(id<<1,l,mid,pos,val,f);
        else modify_max(id<<1|1,mid+1,r,pos,val,f);
        push_up(id);
    }
    
    
    void modify_min(int id,int l,int r,int pos,int val,int f){
    	if(pos<l||pos>r) return ;
        if(l==r){
        	if(f) mins[id]=min(mins[id],val);
            else mins[id]=val;
            return  ;
        }
        int mid=(l+r)>>1;
        if(pos<=mid) modify_min(id<<1,l,mid,pos,val,f);
        else modify_min(id<<1|1,mid+1,r,pos,val,f);
        push_up(id);
    }
    
    
    int query(int id,int l,int r,int pos){
        if(l==r) return num[id];
        int mid=(l+r)>>1;
        if(pos<=mid) return query(id<<1,l,mid,pos);
        else return query(id<<1|1,mid+1,r,pos);
    }
    
    int queryMin(int id,int l,int r,int x,int y){
    //	printf("id=%d l=%d r=%d x=%d y=%d
    ",id,l,r,x,y);
        if(y<l||x>r) return inf;
        if(x<=l&&y>=r) {
        	return mins[id];	
    	}
        int mid=(l+r)>>1,ans=inf;
        if(x<=mid) ans=min(ans,queryMin(id<<1,l,mid,x,y));
        if(y>mid) ans=min(ans,queryMin(id<<1|1,mid+1,r,x,y));
        return ans;
    }
    
    int queryMax(int id,int l,int r,int x,int y){
    //	printf("Max id=%d l=%d r=%d x=%d y=%d
    ",id,l,r,x,y);
        if(y<l||x>r) return 0;
        if(x<=l&&y>=r) {
    //    	debug(maxs[id])
        	return maxs[id];
        }
        int mid=(l+r)>>1,ans=0;
        if(x<=mid) ans=max(ans,queryMax(id<<1,l,mid,x,y));
        if(y>mid) ans=max(ans,queryMax(id<<1|1,mid+1,r,x,y));
        return ans;
    }
    
    int main(){
        int m;
        scanf("%d",&m);
        memset(Min,0,sizeof(Min));
        memset(Max,0,sizeof(Max));
        memset(mins,inf,sizeof(mins));
        memset(maxs,0xef,sizeof(maxs));
    //    printf("%d %d
    ",maxs[0],mins[0]);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&opt[i],&a[i]);
            v[i]=a[i];
        }
        sort(v+1,v+1+m);
        len = unique(v+1,v+1+m)-v-1;
        for(int i=1;i<=m;i++){
            int t=lower_bound(v+1,v+1+len,a[i])-v;
    //        debug(a[i]);
    //        debug(t);
            if(opt[i]==1) {
                int r = query_min(1,1,len,t,len);
    //            debug(r);
                //r>=t
                if(r<=len&&r>=1){
                	modify_min(1,1,len,t,v[r]-v[t],1);
                	modify_max(1,1,len,r,v[r]+v[t],1);
    			}
                int l = query_max(1,1,len,1,t);
    //			debug(l);
                //l<=t
                if(l<=len&&l>=1){
    //            	debug(v[t]);
    //            	debug(v[l]);
                	modify_min(1,1,len,l,v[t]-v[l],1);
                	modify_max(1,1,len,t,v[t]+v[l],1);
    			}
                update(1,1,len,t,1);
            }
            else if(opt[i]==2) {
    //        	debug("second")
                update(1,1,len,t,0);
                int cur = query(1,1,len,t);
    			int r = query_min(1,1,len,t+1,len);
                int l = query_max(1,1,len,1,t-1);
    //            debug(r)
    //            debug(l)
                if(cur==1){
                	if(r) modify_min(1,1,len,t,v[r]-v[t],0);
                	else modify_min(1,1,len,t,inf,0);
                	if(l) modify_max(1,1,len,t,v[l]+v[t],0);
                	else modify_max(1,1,len,t,-inf,0);
    			}
    			else if(cur==0){
    				modify_min(1,1,len,t,inf,0);
                	modify_max(1,1,len,t,-inf,0);
                    if(r) {
                    	int x = query(1,1,len,r);
                    	if(x>=2);
                    	else if(l) modify_max(1,1,len,r,v[l]+v[r],0);
                    	else modify_max(1,1,len,r,-inf,0);
                    }
                   
            		if(l) {
            			int x = query(1,1,len,l);
            			if(x>=2);
    					else if(r) modify_min(1,1,len,l,v[r]-v[l],0);
    					else modify_min(1,1,len,l,inf,0);
    				}
            	
                	
    			}
            }
            else{
            	int flag = 0;
                int r = queryMin(1,1,len,t,len);
                int l = queryMax(1,1,len,1,t);
                int rc = query_min(1,1,len,t+1,len);
                int lc = query_max(1,1,len,1,t-1);
    //            debug(t)
    //            debug(l)
    //            debug(r)
    //            debug(rc)
    //            debug(lc)
                if(rc&&lc&&v[rc]-v[lc]<v[t]) flag = 1;
                if(r<a[i]||l>a[i]) flag = 1;
                if(flag) printf("Yes
    ");
                else printf("No
    ");
            }
        }
    }
    /*
    4
    1 6
    1 4
    2 4
    3 6
    
    
    */ 
    
    
  • 相关阅读:
    MOSS中的User的Title, LoginName, DisplayName, SID之间的关系
    如何在Network Monitor中高亮间隔时间过长的帧?
    SharePoint服务器如果需要安装杀毒软件, 需要注意什么?
    如何查看SQL Profiler? 如何查看SQL死锁?
    什么是Telnet
    The name or security ID (SID) of the domain specified is inconsistent with the trust information for that domain.
    Windows SharePoint Service 3.0的某个Web Application无搜索结果
    网络连接不上, 有TCP错误, 如果操作系统是Windows Server 2003, 请尝试一下这里
    在WinDBG中查看内存的命令
    The virtual machine could not be started because the hypervisor is not running
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/13303954.html
Copyright © 2011-2022 走看看