zoukankan      html  css  js  c++  java
  • 51Nod

    题目链接:传送门

    题目思路:对于每一个笑话,用动态开点线段树来维护区间是否被覆盖(笑话是否已经被这些人听过),先假定范围内全部没听过(置1),然后再将该范围包含的被覆盖的区间置0;

    (也可以用set存一下二元组表示线段左右端点,每次二分查询暴力合并)

    代码:

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    using namespace std;
    typedef long long LL;
    typedef unsigned long long uLL;
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pLL;
    typedef pair<double,double> pdd;
    const int N=1e6+5;
    const int M=2e5+5;
    const int inf=1e8+5;
    const LL mod=1e9+7;
    const double eps=1e-8;
    const long double pi=acos(-1.0L);
    #define ls (i<<1)
    #define rs (i<<1|1)
    #define fi first
    #define se second
    #define pb push_back
    #define eb emplace_back
    #define mk make_pair
    #define mem(a,b) memset(a,b,sizeof(a))
    LL read()
    {
        LL x=0,t=1;
        char ch;
        while(!isdigit(ch=getchar())) if(ch=='-') t=-1;
        while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
        return x*t;
    
    }
    struct node
    {
        int l,r,v;
    };
    node c[N<<3];
    int cnt,rt[N],t[N<<2],lz[N<<2],n,m;
    void pushdown(int i,int l,int r)
    {
        int mid=l+r>>1;
        lz[ls]=lz[rs]=lz[i];
        t[ls]=lz[i]*(mid-l+1);
        t[rs]=lz[i]*(r-mid);
        lz[i]=-1;
    }
    void update(int &now,int l,int r,int ll,int rr)
    {
        if(now==0) now=++cnt;
        if(c[now].v) return ;
        if(ll<=l&&r<=rr) return (void)(c[now].v=1);
        int mid=l+r>>1;
        if(mid>=ll) update(c[now].l,l,mid,ll,rr);
        if(mid<rr) update(c[now].r,mid+1,r,ll,rr);
        c[now].v=min(c[c[now].l].v,c[c[now].r].v);
    }
    int query(int i,int l,int r,int ll,int rr)
    {
        if(ll<=l&&r<=rr) return t[i];
        if(lz[i]!=-1) pushdown(i,l,r);
        int mid=l+r>>1,t1=0,t2=0;
        if(mid>=ll) t1=query(ls,l,mid,ll,rr);
        if(mid<rr) t2=query(rs,mid+1,r,ll,rr);
        return t1+t2;
    }
    void change(int i,int l,int r,int ll,int rr,int x)
    {
        //printf("x = %d , l = %d , r = %d
    ",x,l,r);
        if(ll<=l&&r<=rr) return (void)(t[i]=x*(r-l+1),lz[i]=x);
        if(lz[i]!=-1) pushdown(i,l,r);
        int mid=l+r>>1;
        if(mid>=ll) change(ls,l,mid,ll,rr,x);
        if(mid<rr) change(rs,mid+1,r,ll,rr,x);
        t[i]=t[ls]+t[rs];
    }
    void ask(int now,int l,int r,int ll,int rr)
    {
        if(now==0) return ;
        if(c[now].v)
        {
            change(1,1,n,max(ll,l),min(rr,r),0);
            return ;
        }
        if(ll<=l&&r<=rr&&c[now].v)
        {
            change(1,1,n,l,r,0);//printf("l = %d , r = %d
    ",l,r);
            return ;
        }
        int mid=l+r>>1;
        if(mid>=ll) ask(c[now].l,l,mid,ll,rr);
        if(mid<rr) ask(c[now].r,mid+1,r,ll,rr);
    }
    int main()
    {
        mem(lz,-1);
        n=read(),m=read();
        while(m--)
        {
            int op=read();
            if(op==1){
                int l=read(),x=read(),k=read();
                change(1,1,n,max(1,l-k),min(n,l+k),1);
                ask(rt[x],1,n,max(1,l-k),min(n,l+k));
                update(rt[x],1,n,max(1,l-k),min(n,l+k));
                //printf("x = %d, rt = %d
    ",x,rt[x]);
            }
            else{
                int l=read(),r=read();
                printf("%d
    ",query(1,1,n,l,r));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    boost源码剖析----boost::any
    win10下用Anaconda安装TensorFlow | 后附JetBrains测试
    Could not find conda environment: tensorflow | anaconda激活环境
    Java界面程序实现图片的放大缩小
    JAVA多线程程序ProgressBar2
    JAVA多线程程序ProgressBar
    JAVA记事本的图形用户界面应用程序含过滤
    JAVA记事本的图形用户界面应用程序含加密
    JAVA记事本的图形用户界面应用程序
    Java计算器的图形界面应用程序
  • 原文地址:https://www.cnblogs.com/DeepJay/p/14642093.html
Copyright © 2011-2022 走看看