zoukankan      html  css  js  c++  java
  • 【bzoj1594-猜数游戏】线段树

    题解:

    矛盾只有两种情况:

    一.先前确定了x在区间(l,r),但是现在发现x在区间(l1,r1),并且两个区间不相交。

    二.一个区间的最小值是x,这个区间中有一个子区间的最小值比x更小。

     

    首先可以明确,对于每个x,我们可以不断地缩小x的范围(取区间的交集)。

    那就先处理第一种矛盾,假设第一种矛盾第一次出现是在信息i。

    那么我们就在信息1~i中寻找是否有第二种矛盾(此时保证了1~i中不会有第一种矛盾)。

     

     

    每个信息有l,r,d三个值,我们按照d排序。那就在扫到下面那个区间的时候,我们一定已经有了上面的区间。

    然后我们在线段树里面看红色的这个区间是否已经被完整地覆盖了。

    线段树每个节点维护覆盖这个节点的最前面一个信息(因为题目要求最前的信息)。

    如果红色区间被多个区间加在一起完整覆盖,那我们要去这多个区间的信息的max值(必须等到它也出现了才能完整覆盖)

    最后维护一下ans。

     

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<ctime>
      6 #include<queue>
      7 #include<algorithm>
      8 using namespace std;
      9 
     10 const int N=1000010,INF=(int)1e9;
     11 struct node{int l,r,lc,rc,id,lazy;}t[2*N];
     12 struct nod{int d,id;}p[N];
     13 struct nd{int l,r,d,id;}q[N];
     14 int n,m,tl,L[N],R[N];
     15 
     16 bool cmp_nod(nod x,nod y){return x.d<y.d;}
     17 bool cmp_nd(nd x,nd y)
     18 {
     19     if(x.d!=y.d) return x.d>y.d;
     20     return x.id<y.id;
     21 }
     22 int minn(int x,int y){return x<y ? x:y;}
     23 int maxx(int x,int y){return x>y ? x:y;}
     24 
     25 int buildtree(int l,int r)
     26 {
     27     int x=++tl;
     28     t[x].l=l;t[x].r=r;
     29     t[x].lc=t[x].rc=0;
     30     t[x].id=INF;t[x].lazy=INF;
     31     if(l<r)
     32     {
     33         int mid=(l+r)/2;
     34         t[x].lc=buildtree(l,mid);
     35         t[x].rc=buildtree(mid+1,r);
     36     }
     37     return x;
     38 }
     39 
     40 void upd(int x)
     41 {
     42     if(t[x].lazy==INF) return ;
     43     int id=t[x].lazy,lc=t[x].lc,rc=t[x].rc;
     44     t[x].lazy=INF;
     45     t[x].id=minn(t[x].id,id);
     46     if(lc) t[lc].lazy=minn(t[lc].lazy,id);
     47     if(rc) t[rc].lazy=minn(t[rc].lazy,id);
     48 }
     49 
     50 void change(int x,int l,int r,int id)
     51 {
     52     upd(x);
     53     if(t[x].l==l && t[x].r==r) 
     54     {
     55         t[x].lazy=minn(t[x].lazy,id);
     56         upd(x);
     57         return ;
     58     }
     59     int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)/2;
     60     if(r<=mid) change(lc,l,r,id);
     61     else if(l>mid) change(rc,l,r,id);
     62     else 
     63     {
     64         change(lc,l,mid,id);
     65         change(rc,mid+1,r,id);
     66     }
     67     int now=maxx(t[lc].id,t[rc].id);
     68     if(now<INF) t[x].id=now;//debug 一个小区间都被覆盖了,大区间也会被覆盖。
     69 }
     70 
     71 int query(int x,int l,int r)
     72 {
     73     upd(x);
     74     if(t[x].l==l && t[x].r==r) return t[x].id;
     75     int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)/2;
     76     if(r<=mid) return query(lc,l,r);
     77     else if(l>mid) return query(rc,l,r);
     78     else return maxx(query(lc,l,mid),query(rc,mid+1,r));
     79 }
     80 
     81 
     82 int main()
     83 {
     84     // freopen("a.in","r",stdin);
     85     freopen("bales.in","r",stdin);
     86     freopen("bales.out","w",stdout);
     87     scanf("%d%d",&n,&m);
     88     tl=0;
     89     for(int i=1;i<=m;i++)
     90     {
     91         scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].d);
     92         q[i].id=i;
     93         p[i].d=q[i].d;p[i].id=i;
     94     }
     95     sort(p+1,p+1+m,cmp_nod);
     96     int mx=0;p[0].d=0;
     97     for(int i=1;i<=m;i++) 
     98     {
     99         if(p[i].d!=p[i-1].d) mx++;
    100         q[p[i].id].d=mx;
    101     }
    102     for(int i=1;i<=mx;i++) L[i]=1,R[i]=n;
    103     int ans=INF;
    104     for(int i=1;i<=m;i++)
    105     {
    106         int x=q[i].d;
    107         if(q[i].l>R[x] || q[i].r<L[x]) {ans=i;m=i-1;break;}
    108         L[x]=maxx(L[x],q[i].l);
    109         R[x]=minn(R[x],q[i].r);
    110     }
    111     // printf("%d
    ",ans);
    112     buildtree(1,n);
    113     sort(q+1,q+1+m,cmp_nd);
    114     for(int i=1;i<=mx;i++) L[i]=1,R[i]=n;
    115     int x,now,j=1;
    116     for(int i=1;i<=m;i++)
    117     {
    118         while(j<i && q[j].d!=q[i].d) 
    119         {
    120             change(1,q[j].l,q[j].r,q[j].id);
    121             j++;
    122         }
    123         x=q[i].d;
    124         L[x]=maxx(L[x],q[i].l);
    125         R[x]=minn(R[x],q[i].r);
    126         now=query(1,L[x],R[x]);
    127         ans=minn(ans,maxx(q[i].id,now));
    128     }
    129     if(ans<INF) printf("%d
    ",ans);
    130     else printf("0
    ");
    131     return 0;
    132 }

     

  • 相关阅读:
    杭电dp题集,附链接还有解题报告!!!!!
    js正則表達式语法
    java界面编程(8) ------ 组合框(下拉列表)
    四个好看的CSS样式表格
    搜集朋友写的几篇Android Elf相关的文档
    hadoop编程小技巧(5)---自己定义输入文件格式类InputFormat
    递归算法
    ua识别(浏览器标识识别)
    amazeui学习笔记一(开始使用5)--藏品collections
    amazeui学习笔记一(开始使用4)--Web App 相关
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/6016553.html
Copyright © 2011-2022 走看看