zoukankan      html  css  js  c++  java
  • LOJ #2732. 「JOISC 2016 Day 2」雇佣计划 线段树

    题意:给定一个数列,单点修改,求大于 $b_{i}$ 的极大连通块数目.  

    有一个常见的套路:考虑 $i$ 与 $i-1$.  

    当新加入 $i$ 时,$1$ ~ $a[i]$ 部分都新加入了一个连通块,然后我们发现我们多加了 $1$ ~ $min(a[i-1],a[i])$ 这一部分.  

    那么这就对应了一个区间修改,单点查询,用线段树即可. 

    code:  

    #include <bits/stdc++.h>    
    #define ll long long 
    #define N 200006     
    #define lson now<<1 
    #define rson now<<1|1  
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std; 
    int n,m;        
    int sum[N<<3],lazy[N<<3],a[N],A[N<<2];  
    struct node
    {
        int op,a,b;  
        node(int op=0,int a=0,int b=0):op(op),a(a),b(b){}  
    }s[N<<2];  
    void update(int l,int r,int now,int L,int R,int v) 
    {   
        if(l>=L&&r<=R)  
        {
            lazy[now]+=v;   
            sum[now]+=(r-l+1)*v;   
            return;  
        }
        int mid=(l+r)>>1;    
        if(L<=mid)   
            update(l,mid,lson,L,R,v);  
        if(R>mid)  
            update(mid+1,r,rson,L,R,v);  
        sum[now]=sum[lson]+sum[rson]+(r-l+1)*lazy[now];   
    }    
    int query(int l,int r,int now,int L,int R) 
    {
        if(l>=L&&r<=R)  
            return sum[now];  
        int mid=(l+r)>>1,re=(min(r,R)-max(l,L)+1)*lazy[now];   
        if(L<=mid)   
            re+=query(l,mid,lson,L,R);  
        if(R>mid)  
            re+=query(mid+1,r,rson,L,R);  
        return re;  
    }   
    int main() 
    { 
        //  setIO("input");  
        int i,j,tot=0;    
        scanf("%d%d",&n,&m);    
        for(i=1;i<=n;++i) 
            scanf("%d",&a[i]),A[++tot]=a[i];  
        for(i=1;i<=m;++i) 
        {
            scanf("%d",&s[i].op);   
            if(s[i].op==1)  
                scanf("%d",&s[i].b),A[++tot]=s[i].b;    
            else    
                scanf("%d%d",&s[i].a,&s[i].b),A[++tot]=s[i].b;   
        }  
        sort(A+1,A+1+tot);  
        for(i=1;i<=n;++i)  
            a[i]=lower_bound(A+1,A+1+tot,a[i])-A;  
        for(i=1;i<=m;++i)   
            s[i].b=lower_bound(A+1,A+1+tot,s[i].b)-A;    
        for(i=1;i<=n;++i) 
        {
            update(1,tot,1,1,a[i],1);            
            if(i>1) 
                update(1,tot,1,1,min(a[i],a[i-1]),-1);     
        }   
        for(i=1;i<=m;++i) 
        {
            if(s[i].op==1)
                printf("%d
    ",query(1,tot,1,s[i].b,s[i].b));    
            else 
            {  
                int cur=s[i].a;   
                update(1,tot,1,1,a[cur],-1);                
                if(cur>1)
                {
                    update(1,tot,1,1,min(a[cur],a[cur-1]),1);        
                }
                if(cur<n)   
                { 
                    update(1,tot,1,1,min(a[cur],a[cur+1]),1);              
                }
                a[cur]=s[i].b;   
                update(1,tot,1,1,a[cur],1);   
                if(cur>1)
                    update(1,tot,1,1,min(a[cur],a[cur-1]),-1);        
                if(cur<n)   
                    update(1,tot,1,1,min(a[cur],a[cur+1]),-1);   
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    27-Perl 进程管理
    26-Perl 包和模块
    25-Perl CGI编程
    YUM极速安装mariadb
    yum极速安装mysql5.7
    切换阿里yum镜像源
    mysql生成随机字符串函数
    Unable to locate value meta plugin of type (id)
    centos 挂载NTFS移动硬盘
    总有你要的编程书单(GitHub )
  • 原文地址:https://www.cnblogs.com/guangheli/p/12483571.html
Copyright © 2011-2022 走看看