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

    • H.Happy Triangle

    • 维护一个集合。集合支持三种操作。1、往集合里加入一个元素x。2、往集合里删除一个容器x。3、给定一个x,询问是否能从容器找找到y,z,使得x,y,z能组成三角形。操作数<=10^5,x<=10^9。

    • 先将所有的x离散化。然后可用权值线段树。维护权值线段树的最大值最小值,数量和区间最小差值。

    • 总共有三种可能。

    • 1、x<=y<=z 此时,我们需要找到y-z的最小差值。这就是要维护区间最小差的原因。

    • 2、y<=x<=z 此时,需要找到小于x且最大的y,大于x且最小的z,然后判断能否组成三角形。线段树上直接搜即可。

    • 3、y<=z<=x 此时,找到小于x且前2大的数,然后判断能否组成三角形。

    • #include
      #define N 205000
      #define inf 0x3f3f3f3f
      using namespace std;
      map mp;
      int a[N];
      int b[N];
      int op[N];
      int n;
      void lisan() {
      	int i,x;
      	for (i=1;i<=n;i++) b[i]=a[i];
      	sort(b+1,b+1+n);
      	for (i=1;i<=n;i++) {
      		x=lower_bound(b+1,b+1+n,a[i])-b;
      		mp[x]=a[i];
      		a[i]=x;
      	}	
      }
      struct node{
      	int left,right,interval,sum;
      }tree[N<<2];
      void pushup(int rt) {
      	tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
      	tree[rt].interval=min(tree[rt<<1].interval,tree[rt<<1|1].interval);
      	tree[rt].left=min(tree[rt<<1].left,tree[rt<<1|1].left);
      	tree[rt].right=max(tree[rt<<1].right,tree[rt<<1|1].right);
      	if (tree[rt<<1].sum>0&&tree[rt<<1|1].sum>0) 
      		tree[rt].interval=min(tree[rt].interval,mp[tree[rt<<1|1].left]-mp[tree[rt<<1].right]);
      		
      }
      void build(int l,int r,int rt){
      	if (l==r) {
      		tree[rt].left=inf;
      		tree[rt].right=0;
      		tree[rt].sum=0;
      		tree[rt].interval=inf;
      		return ;
      	}
      	int m=(l+r)>>1;
      	build(l,m,rt<<1);
      	build(m+1,r,rt<<1|1);
      	pushup(rt);
      }
      void add(int l,int r,int x,int s,int rt) {
      	if (l==r) {
      		tree[rt].sum+=s;
      		if (tree[rt].sum>0) {
      			tree[rt].left=x;
      			tree[rt].right=x;
      		} else {
      			tree[rt].left=inf;
      			tree[rt].right=0;
      		}
      		if (tree[rt].sum>1) tree[rt].interval=0;
      			else tree[rt].interval=inf;
      		return;
      	}
      	int m=(l+r)>>1;
      	if (x<=m) add(l,m,x,s,rt<<1);
      	else add(m+1,r,x,s,rt<<1|1);
      	pushup(rt);
      	
      }
      int query_max(int l,int r,int x,int rt) {
      	if (tree[rt].sum==0) {
      		return -1;
      	}
      	if (l==r) {
      		return tree[rt].left;
      	}
      	int m=(l+r)>>1;
      	if (x<=m) return query_max(l,m,x,rt<<1);
      	else return max(tree[rt<<1].right,query_max(m+1,r,x,rt<<1|1));
      }
      int query_min(int l,int r,int x,int rt) {
      	if (tree[rt].sum==0) {
      		return inf;
      	}
      	if (l==r) {
      		return tree[rt].left;
      	}
      	int m=(l+r)>>1;
      	if (x>m) return query_min(m+1,r,x,rt<<1|1);
      	else return min(tree[rt<<1|1].left,query_min(l,m,x,rt<<1));
      }
      
      node query_int(int l,int r,int x,int rt) {
      	node tmp,re;
      	if (tree[rt].sum==0) {
      		return tree[rt];
      	}
      	if (l==r) {
      		return tree[rt];
      	}
      	int m=(l+r)>>1;
      	if (x>m) return query_int(m+1,r,x,rt<<1|1);
      	else { 
      		tmp=query_int(l,m,x,rt<<1);
      		re.sum=tmp.sum+tree[rt<<1|1].sum;
      		re.interval=min(tmp.interval,tree[rt<<1|1].interval);
      		re.left=min(tmp.left,tree[rt<<1|1].left);
      		re.right=max(tmp.right,tree[rt<<1|1].right);
      		if (tmp.sum>0&&tree[rt<<1|1].sum>0) 
      		re.interval=min(re.interval,mp[tree[rt<<1|1].left]-mp[tmp.right]);
      		return re;
      	}
      }
      
      int main(){
      	int e,t,x,y;
      	node p;
      	int i;
      	scanf("%d",&n);
      	for (i=1;i<=n;i++) scanf("%d %d",&op[i],&a[i]);
      	lisan();
      	build(1,n,1);
      	for (i=1;i<=n;i++) {
      		if (op[i]==1) {
      			add(1,n,a[i],1,1);
      		}
      		if (op[i]==2) {
      			add(1,n,a[i],-1,1);
      		}
      		if (op[i]==3) {
      			//x<=a[i]<=y
      			x=query_max(1,n,a[i],1); // max<=a[i]
      			add(1,n,x,-1,1);
      			y=query_min(1,n,a[i],1);
      			add(1,n,x,1,1);
      			if (x!=-1&&y!=inf) if (mp[x]+mp[a[i]]>mp[y]) {printf("Yes
      ");continue;}
      			y=query_min(1,n,a[i],1);// max<=a[i]
      			add(1,n,y,-1,1);
      			x=query_max(1,n,a[i],1); 
      			add(1,n,y,1,1);
      			if (x!=-1&&y!=inf) if (mp[x]+mp[a[i]]>mp[y]) {printf("Yes
      ");continue;}
      			//a[i]<=x<=y
      			p=query_int(1,n,a[i],1);
      			x=p.interval;
      			if (x!=inf) if (mp[a[i]]>x) {printf("Yes
      ");continue;}
      			//x<=y<=a[i]
      			x=query_max(1,n,a[i],1);
      			add(1,n,x,-1,1);
      			y=query_max(1,n,a[i],1);
      			add(1,n,x,1,1);
      			if (x!=-1&&y!=-1)
      			if (mp[x]+mp[y]>mp[a[i]]) {printf("Yes
      ");continue;}
      			printf("No
      ");
      		}
      	}
      }
      
      
  • 相关阅读:
    STL map
    HDU1372 Knight Moves BFS
    HDU1072 Nightmare BFS
    discuz论坛发帖添加字段
    gridview自定义button事件 ,无法触发 onrowcommand
    discuz 怎么开启评分!!!
    discuz学习网站收集
    discuz扩展工具集合
    童话世界整理“说说”
    asp.net中Literal与label的区别
  • 原文地址:https://www.cnblogs.com/nowheretrix/p/13326393.html
Copyright © 2011-2022 走看看