zoukankan      html  css  js  c++  java
  • 线段树处理集合里的最小差值

    题意:给你一个集合,集合里没有重复元素。集合可以添加元素,也可以删除元素(前提是集合里有),另外还有一个询问操作,问集合里最小的差值是多少(只有一个元素的时候询问无效)

    例如,集合开始的时候有1 7两个元素,那么最小差值就是6。当再添加一个新的元素3,集合就变成了1 3 7,那么最小差值就是2。

    解法:对于每一个区间线段,我们给它3个属性,最小值minf,最大值maxf,以及最小差值deff。

    从下而上,我们很容易可以看出,某一个线段 i 的最小值为min(left_child[i].minf,right_child[i].minf)

                                                                 最大值为max(left_child[i].maxf,right_child[i].maxf)

                                                                最小差值等于min(min(左右子区间的最小差值),右子区间的最小值减去左子区间的最大值)

    View Code
      1 #include<iostream>
      2 #include<string>
      3 #include<cmath>
      4 #include<algorithm>
      5 using namespace std;
      6 #define inf 0xfffffff
      7 
      8 struct node
      9 {
     10     int l;
     11     int r;
     12     int minf; //该区间最小值
     13     int maxf; //该区间最大值
     14     int deff; //该区间的最小差值
     15 };
     16 
     17 node tree[1000000];
     18 
     19 int max(int a,int b)
     20 {
     21     return a>b?a:b;
     22 }
     23 
     24 int min(int a,int b)
     25 {
     26     return a<b?a:b;
     27 }
     28 
     29 void build(int i,int l,int r)
     30 {
     31     tree[i].l=l;
     32     tree[i].r=r;
     33     tree[i].minf=inf;
     34     tree[i].maxf=-inf;
     35     tree[i].deff=inf;
     36     if(l==r)
     37         return;
     38     int mid=(l+r)/2;
     39     build(2*i,l,mid);
     40     build(2*i+1,mid+1,r);
     41 }
     42 
     43 int query()
     44 {
     45     return tree[1].deff<100100?tree[1].deff:-1;
     46 }
     47 
     48 void updata(int i)
     49 {
     50     tree[i].minf=min(tree[2*i].minf,tree[2*i+1].minf);
     51     tree[i].maxf=max(tree[2*i].maxf,tree[2*i+1].maxf);
     52     tree[i].deff=min(tree[2*i].deff,tree[2*i+1].deff);
     53     tree[i].deff=min(tree[i].deff,tree[2*i+1].minf-tree[2*i].maxf);
     54 }
     55 
     56 void add(int i,int l,int r)
     57 {
     58     if(tree[i].l>r || tree[i].r<l)
     59         return;
     60     if(tree[i].l>=l && tree[i].r<=r)
     61     {
     62         tree[i].maxf=l;
     63         tree[i].minf=l;
     64         return;
     65     }
     66     add(2*i,l,r);
     67     add(2*i+1,l,r);
     68     updata(i);
     69 }
     70 
     71 void det(int i,int l,int r)
     72 {
     73     if(tree[i].l>r || tree[i].r<l)
     74         return;
     75     if(tree[i].l>=l && tree[i].r<=r)
     76     {
     77         tree[i].maxf=-inf;
     78         tree[i].minf=inf;
     79         return;
     80     }
     81     det(2*i,l,r);
     82     det(2*i+1,l,r);
     83     updata(i);
     84 }
     85 
     86 int main()
     87 {
     88     int cas,n,a,flag=0;
     89     char str[20];
     90     freopen("E.in","r",stdin);
     91     freopen("E.out","w",stdout);
     92     scanf("%d",&cas);
     93     while(cas--)
     94     {
     95         if(flag)
     96             printf("\n");
     97         flag=1;
     98         scanf("%d",&n);
     99         build(1,1,100000);
    100         while(n--)
    101         {
    102             scanf("%*c%s",str);
    103             if(str[0]=='g')
    104             {
    105                 scanf("%d",&a);
    106                 add(1,a,a);
    107             }
    108             else if(str[0]=='r')
    109             {
    110                 scanf("%d",&a);
    111                 det(1,a,a);
    112             }
    113             else
    114             {
    115                 a=query();
    116                 printf("%d\n",a);
    117             }
    118         }
    119     }
    120     return 0;
    121 }
  • 相关阅读:
    gulp+browser-sync使用方法
    小程序试用体验
    移动端调试总结
    函数防抖和函数分流
    页面返回顶部的方法总结
    POJ
    POJ
    UVA 10129 Play on Words(欧拉道路)
    UVA 10305 Ordering Tasks (拓扑排序)
    UVA 12657 Boxes in a Line(双向链表+小技巧)
  • 原文地址:https://www.cnblogs.com/ka200812/p/2716551.html
Copyright © 2011-2022 走看看