zoukankan      html  css  js  c++  java
  • [bzoj 1594]猜数游戏

    主要是怎么处理矛盾

    矛盾的条件有$2$种:

    第一种是当把所有相等的$a$都全部找到后,他们并没有全联通,所以矛盾,因为没有两个是相同的

    第二种是在2组$(l,r,a)$,$(l1,r1,a1)$中,$a<a1$并且$(l,r)$ 包含在$(l1,r1)$,矛盾

    所以怎么去维护,第一种直接暴力查询,第二种我们可以从大到小排序$minn$,去在线段树中维护并集操作,看一看是否被覆盖即可

    此答案具有单调性,所以可以通过二分优化

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define int long long
    using namespace std;
    inline int read()
    {
        int f=1,ans=0;char c;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    struct node{
        int l,r,minn;
    }x[10000001],st[10000001];
    int flag[8000001],n,q,maxn,inf=(int)1<<61;
    bool cmp(node x1,node x2){return x1.minn>x2.minn;}
    void pushdown(int k,int l,int r){
        if(!flag[k]) return;
        flag[k<<1]=flag[k<<1|1]=1;
        flag[k]=0;return;
    }
    void update(int k,int l,int r,int x,int y){
    //    cout<<x<<" "<<y<<endl;
        if(x<=l&&r<=y){flag[k]=1;return;}
        pushdown(k,l,r);
        int mid=l+r>>1;
        if(x<=mid) update(k<<1,l,mid,x,y);
        if(mid<y) update(k<<1|1,mid+1,r,x,y);
        flag[k]=flag[k<<1]&flag[k<<1|1];
        return;
    }
    int query(int k,int l,int r,int x,int y){
        if(x<=l&&r<=y) return flag[k];
        pushdown(k,l,r);
        int mid=l+r>>1;
        int kkk=1;
        if(x<=mid) kkk&=query(k<<1,l,mid,x,y);
        if(mid<y) kkk&=query(k<<1|1,mid+1,r,x,y);
        flag[k]=flag[k<<1]&flag[k<<1|1];
        return kkk; 
    }
    bool check(int len){
    //    cout<<"len:"<<len<<endl;return 0;
        memset(flag,0,sizeof(flag));
        for(int i=1;i<=len;i++) st[i]=x[i];
        sort(st+1,st+len+1,cmp);
        int j;
        for(int i=1;i<=len;i=j+1){
            j=i;
            while(j<=len&&st[j].minn==st[i].minn) j++;--j;
            int l1=inf,r1=inf,l2=0,r2=0;
            for(int k=i;k<=j;k++){
                
                l1=min(l1,st[k].l);l2=max(l2,st[k].l);
                r1=min(r1,st[k].r),r2=max(r2,st[k].r);
            }
            if(l2>r1) return 0;
            if(query(1,1,n,l2,r1)) return 0;
            update(1,1,n,l1,r2);
        }return 1;
    }
    signed main()
    {
        n=read(),q=read();
        for(int i=1;i<=q;i++) {
            x[i].l=read(),x[i].r=read(),x[i].minn=read();
        }
        int l=1,r=q,mid;
        while(l<=r){
            mid=l+r>>1;
            if(check(mid)) maxn=max(maxn,mid),l=mid+1;
            else r=mid-1;
        }
        if(maxn!=q) cout<<maxn+1;
        else cout<<0;
    }
    View Code
  • 相关阅读:
    014_v2 python基础语法_dict
    6-05使用SQL语句删除数据
    6-04使用SQL语句更新数据
    6-03使用SQL语句一次型向表中插入多行数据
    6-02使用SQL语句向表中插入数据
    6-01T-SQL中的运算符
    5-08删除表
    5-07删除约束
    使用SQL语句向已有数据表添加约束
    5-06使用Sql 语句为表添加约束
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/9889984.html
Copyright © 2011-2022 走看看