zoukankan      html  css  js  c++  java
  • 【模板】【线段树】

    1>区间加法+区间和询问

    #include<cstdio>
    #include<cstdlib>
    #define int long long
    using namespace std;
    int n,m;
    const int N=1e6+3;
    int d[N];
    struct node
    {
        int son1,son2;
        int sum,laz,len;
    }tr[N<<2];
    int root,cnt;
    void updata(int rt)
    {
        int a=tr[rt].son1 ,b=tr[rt].son2 ;
        tr[rt].sum =tr[a].sum +tr[b].sum ;
    }
    void build(int &rt,int l,int r)
    {
        rt=++cnt;
        tr[rt].len =r-l+1;
        if(l==r) 
        {
            tr[rt].sum =d[l];
            return ;
        }
        int mid=(l+r)>>1;
        build(tr[rt].son1 ,l,mid);
        build(tr[rt].son2 ,mid+1,r);
        updata(rt);
    }
    void push_down(int rt)
    {
        int a=tr[rt].son1 ,b=tr[rt].son2 ,v=tr[rt].laz ;
        tr[a].laz +=v,tr[b].laz +=v;
        tr[a].sum +=v*tr[a].len ,tr[b].sum +=v*tr[b].len ;
        tr[rt].laz =0;
    }
    void change(int rt,int l,int r,int ll,int rr,int vv)
    {
        if(ll<=l && r<=rr)
        {
            tr[rt].laz +=vv,tr[rt].sum +=tr[rt].len *vv;
            return ;
        }
        if(tr[rt].laz ) push_down(rt);
        int mid=(l+r)>>1;
        if(rr<=mid) change(tr[rt].son1 ,l,mid,ll,rr,vv);
        else if(ll>mid) change(tr[rt].son2 ,mid+1,r,ll,rr,vv);
        else change(tr[rt].son1 ,l,mid,ll,mid,vv),change(tr[rt].son2 ,mid+1,r,mid+1,rr,vv);//有影响??? 
        updata(rt);
    } 
    int query(int rt,int l,int r,int ll,int rr)
    {
        if(ll<=l && r<=rr)
            return tr[rt].sum ;
        if(tr[rt].laz ) push_down(rt);  
        int mid=(l+r)>>1;
        if(rr<=mid) return query(tr[rt].son1 ,l,mid,ll,rr); 
        else if(ll>mid) return query(tr[rt].son2 ,mid+1,r,ll,rr);
        return query(tr[rt].son1 ,l,mid,ll,rr)+query(tr[rt].son2 ,mid+1,r,ll,rr);
    }
    
    signed main()
    {
        scanf("%lld%lld",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%lld",&d[i]);
        build(root,1,n);
        
        int op,ll,rr,vv;
        while(m--)
        {
            scanf("%lld%lld%lld",&op,&ll,&rr);
            if(op==1)
            {
                scanf("%lld",&vv);
                change(1,1,n,ll,rr,vv); 
            }
            else
                printf("%lld
    ",query(1,1,n,ll,rr));
        }
        
        return 0;
    }

    2>区间加法+区间乘法+区间和询问

    自设:d[i]*mul +add

    #include<cstdio>
    #include<cstdlib>
    #define int long long
    using namespace std;
    int n,m,mod;
    const int N=1e5+3;
    int d[N],root,cnt;
    
    struct node
    {
        int son1,son2,len;
        int sum,laz,LAZ;
        //加,乘两个标记,选择d*LAZ+laz
        //add时,直接加
        //mul时,如果laz!=0,就push_down再乘
        //push_down时,如果LAZ!=1  =》  将孩子的laz,LAZ,sum都*mul
        //再处理laz 
    }tr[N*3];
    void updata(int rt)
    {
        tr[rt].sum=(tr[tr[rt].son1].sum +tr[tr[rt].son2].sum)%mod;
    } 
    void build(int &rt,int l,int r)
    {
        rt=++cnt;
        tr[rt].LAZ =1,tr[rt].len =r-l+1;
        if(l==r)
        {
            tr[rt].sum=d[l]%mod;
            return ;
        }
        int mid=(l+r)>>1;
        build(tr[rt].son1 ,l,mid);
        build(tr[rt].son2 ,mid+1,r);
        updata(rt);
    }
    
    void push_down(int rt)
    {
        int a=tr[rt].son1 ,b=tr[rt].son2 ;
        if(tr[rt].LAZ !=1)
        {
            int t=tr[rt].LAZ ;
            tr[a].sum =(tr[a].sum *t)%mod;
            tr[a].LAZ =(tr[a].LAZ *t)%mod;
            tr[a].laz =(tr[a].laz *t)%mod;
            tr[b].sum =(tr[b].sum *t)%mod;
            tr[b].LAZ =(tr[b].LAZ *t)%mod;
            tr[b].laz =(tr[b].laz *t)%mod;
            tr[rt].LAZ =1;
        }
        if(tr[rt].laz )
        {
            int t=tr[rt].laz ;
            tr[a].sum =(tr[a].sum +t*tr[a].len )%mod;
            tr[a].laz =(tr[a].laz +t)%mod;
            tr[b].sum =(tr[b].sum +t*tr[b].len )%mod;//写掉了len... 
            tr[b].laz =(tr[b].laz +t)%mod;
            tr[rt].laz =0;
        }
    }
    void add(int rt,int l,int r,int ql,int qr,int v)
    {
        if(ql<=l && r<=qr)
        {
            tr[rt].sum =(tr[rt].sum + v*tr[rt].len%mod)%mod;
            tr[rt].laz =(tr[rt].laz + v)%mod;
            return ;
        }
        push_down(rt);
    
        int mid=(l+r)>>1;
        if(qr<=mid) add(tr[rt].son1 ,l,mid,ql,qr,v);
        else if(ql>mid) add(tr[rt].son2 ,mid+1,r,ql,qr,v);
        else add(tr[rt].son1 ,l,mid,ql,mid,v),add(tr[rt].son2 ,mid+1,r,mid+1,qr,v);
        updata(rt);
    }
    void mul(int rt,int l,int r,int ql,int qr,int v)
    {
        if(ql<=l && r<=qr)
        {
            tr[rt].sum =(tr[rt].sum *v)%mod;
            tr[rt].laz =(tr[rt].laz *v)%mod;
            tr[rt].LAZ =(tr[rt].LAZ *v)%mod;
            return ;
        }
        push_down(rt);
    
        int mid=(l+r)>>1;
        if(qr<=mid) mul(tr[rt].son1 ,l,mid,ql,qr,v);
        else if(ql>mid) mul(tr[rt].son2 ,mid+1,r,ql,qr,v);
        else mul(tr[rt].son1 ,l,mid,ql,qr,v),mul(tr[rt].son2 ,mid+1,r,ql,qr,v);
        updata(rt);
    }
    
    int query(int rt,int l,int r,int ql,int qr)
    {
        if(ql<=l && r<=qr)
            return tr[rt].sum ;
        push_down(rt);
        int mid=(l+r)>>1;
        if(qr<=mid) return query(tr[rt].son1 ,l,mid,ql,qr);
        else if(ql>mid) return query(tr[rt].son2 ,mid+1,r,ql,qr);
        else return (query(tr[rt].son1 ,l,mid,ql,mid)+query(tr[rt].son2 ,mid+1,r,mid+1,qr))%mod;
    }
    
    signed main()
    {
        scanf("%lld%lld%lld",&n,&m,&mod);
        for(int i=1;i<=n;i++)
            scanf("%lld",&d[i]);
        build(root,1,n);
        
        int op,x,y,k;
        for(int i=1;i<=m;i++)
        {
            scanf("%lld%lld%lld",&op,&x,&y);
            if(op==3)
                printf("%lld
    ",query(1,1,n,x,y));
            else if(op==1)
                scanf("%lld",&k),mul(1,1,n,x,y,k%mod);
            else if(op==2)
                scanf("%lld",&k),add(1,1,n,x,y,k%mod);
        }
        
        return 0;
    } 

     3>离散+统计线段数

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int n,m;
    const int N=100003;
    int op[N][4];//l,r,op,v
    struct node
    {
        int d,id,wz;
        bool operator < (const node & o) const 
        {
            return d<o.d;
        }
    }d[N*2];
    void ls()
    {
        scanf("%d %d",&n,&m);
        char s[10];int l,r,v;
        for(int i=0;i<m;i++)
        {
            scanf("%s %d %d",s,&l,&r);
            if(l>r) swap(l,r);
            op[i][0]=l,op[i][1]=r;
            if(s[0]=='C')
                scanf("%d",&v),op[i][2]=1,op[i][3]=v;
            d[i*2].d =l,d[i*2+1].d =r;
            d[i*2].id =d[i*2+1].id =i;
            d[i*2].wz =0,d[i*2+1].wz =1;
        }
        sort(d,d+2*m);
        int last=0,w=0;
        for(int i=0;i<2*m;i++)
        {
            if(d[i].d !=last)
            {
                w++;
                if(d[i].d >last+1) w++;
                last=d[i].d ;
                op[d[i].id ][d[i].wz ]=w;
            }
            else
                op[d[i].id ][d[i].wz ]=w;
        }
        n=w;
    }
    int root,tot;
    struct no
    {
        int l,r,lc,rc,col;
        bool flag;//true为纯色 
    }tree[N*3];
    void updata(int rt)
    {
        int lc=tree[rt].lc ,rc=tree[rt].rc ;
        if(tree[lc ].flag && tree[rc ].flag && tree[lc ].col ==tree[rc ].col )
            tree[rt].flag =true,tree[rt].col =tree[lc ].col ;
    }
    void create(int &rt,int l,int r)
    {
        rt=tot++;
        tree[rt].l =l,tree[rt].r =r;
        tree[rt].lc =tree[rt].rc =-1;
        tree[rt].flag =true;
        if(l==r)
            tree[rt].col =1;
        else
        {
            int mid=(l+r)/2;
            create(tree[rt].lc ,l,mid);
            create(tree[rt].rc ,mid+1,r);
            updata(rt);
        }
    }
    void pushdown(int rt)
    {
        int lc=tree[rt].lc ,rc=tree[rt].rc ;
        tree[lc].flag =tree[rc].flag =true;
        tree[lc].col =tree[rc].col =tree[rt].col ;
        tree[rt].flag =false;
    }
    void change(int rt,int l,int r,int v)
    {
        int ll=tree[rt].l ,rr=tree[rt].r;
        if(l<=ll&&rr<=r)
            tree[rt].flag =true,tree[rt].col =v;
        else
        {
            if(tree[rt].flag ) pushdown(rt);
            int mid=(ll+rr)/2;
            if(r<=mid) change(tree[rt].lc ,l,r,v);
            else
                if(l>mid) change(tree[rt].rc ,l,r,v);
                else
                    change(tree[rt].lc ,l,mid,v),
                    change(tree[rt].rc ,mid+1,r,v);
        }
    }
    bool f[53];
    void dfs(int rt,int l,int r)
    {
        if(tree[rt].flag )
            f[tree[rt].col ]=true;
        else
        {
            int ll=tree[rt].l ,rr=tree[rt].r ;
            int mid=(ll+rr)/2;
            if(r<=mid)  dfs(tree[rt].lc ,l,r);
            else
                if(l>mid) dfs(tree[rt].rc ,l,r);
                else dfs(tree[rt].lc ,l,mid),dfs(tree[rt].rc ,mid+1,r);
        }
    }
    int main()
    {
        ls();
        create(root,1,n);
        for(int i=0;i<m;i++)
        {
            if(op[i][2]==1)
                change(root,op[i][0],op[i][1],op[i][3]);
            else
            {
                memset(f,false,sizeof(f));
                dfs(root,op[i][0],op[i][1]);
                int ans=0;
                for(int i=0;i<=50;i++)
                    if(f[i]) ans++;
                printf("%d
    ",ans);
            }
        }
        return 0;
    } 
  • 相关阅读:
    div地图中display设置为none引起的报错
    onclick事件传参
    获取,设置任意标签的任意属性值
    ajax局域变量赋值给全局变量
    eclipse整合maven打包的时候跳过测试
    测网络ip,端口互通命令
    关于局域网地址ping不通的问题
    Error starting static Resources java.lang.IllegalArgumentException: Document base F:Soft omcatwebappspms-site does not exist or is not a readable directory
    回顾创建项目报错
    记录一次webpackJsonp is not defined
  • 原文地址:https://www.cnblogs.com/xwww666666/p/11608923.html
Copyright © 2011-2022 走看看