zoukankan      html  css  js  c++  java
  • 回档|校门外的树3|线段树的应用

    描述
     

       校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的……
    如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作:
    K=1,读入l,r表示在l~r之间种上的一种树
    K=2,读入l,r表示询问l~r之间能见到多少种树
    (l,r>0)
    输入格式
    第一行n,m表示道路总长为n,共有m个操作
    接下来m行为m个操作
    输出格式
    对于每个k=2输出一个答案

    备注
    范围:20%的数据保证,n,m<=100
          60%的数据保证,n <=1000,m<=50000
          100%的数据保证,n,m<=50000
    注意:树是可以重叠的,比如1号位置上可以种多种树

    解析:这题可以这么做,建立两棵线段树,分别维护这个点之前有几个左括号和这个点之后有几个右括号,于是就可以做啦。

    代码:
    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    struct node{
        int s,t,l,r;
    }tr[800001];
    int n,q;
    int a[200001];
    
    int read()
    {
        char c=getchar();
        int a=0;
        while (c<'0'||c>'9') c=getchar();
        while (c>='0'&&c<='9')
        {
              a=a*10+c-'0';
              c=getchar();
        }
        return a;
    }
    
    void build(int k,int x,int y)
    {
        tr[k].s=x; tr[k].t=y;
        if (x==y) { tr[k].l=tr[k].r=0; return; }
        int mid=(x+y)>>1;
        build(k<<1,x,mid);
        build(k<<1|1,mid+1,y);
        return;
    }
    
    void insertl(int now,int x,int y)
    {
        int l=tr[now].s,r=tr[now].t;
        //if (y
        if (x==l && y==r)
        {
            tr[now].l+=1;
            return;
        }
        int mid=(l+r)>>1;
        if (x>mid) insertl(now<<1|1,x,y);
            else if (y<=mid) insertl(now<<1,x,y);
                else { insertl(now<<1,x,mid); insertl(now<<1|1,mid+1,y);        }
        return;
    }
    
    void insertr(int now,int x,int y)
    {
        int l=tr[now].s,r=tr[now].t;
        //if (y
        if (x==l && y==r)
        {
            tr[now].r+=1;
            return;
        }
        int mid=(l+r)>>1;
        if (x>mid) insertr(now<<1|1,x,y);
            else if (y<=mid) insertr(now<<1,x,y);
                else { insertr(now<<1,x,mid); insertr(now<<1|1,mid+1,y);        }
        return;
    }
    
    int findl(int k,int x)
    {
        int l=tr[k].s,r=tr[k].t;
        //if (y
        if (l==r) return tr[k].l;
        int mid=(l+r)>>1;
        if (x<=mid) return tr[k].l+findl(k<<1,x);
            else return tr[k].l+findl(k<<1|1,x);
       
    }
    
    int findr(int k,int x)
    {
        int l=tr[k].l,r=tr[k].r;
        if (l==r) return tr[k].r;
        int mid=(l+r)>>1;
        if (x<=mid) return tr[k].r+findr(k<<1,x);
            else return tr[k].r+findr(k<<1|1,x);
    }
    
    int main()
    {
            int total=0;
            n=read();
            build(1,0,n);
            q=read();
            for (int i=1; i<=q; i++)
            {
                int now=read();
                int x=read(),y=read();
                if (now==1)
                {
                    insertl(1,0,x-1);
                    insertr(1,y+1,n);
                    total++;
                }
                else if (now==2)
                {
                    int ans1=findr(1,x);
                    int ans2=findl(1,y);
                    int ans=ans1+ans2;
                    //cout << ans1 << ' ' << ans2 << "hh"  << endl;
                    printf("%lld
    ",total-ans);
                }
            }
            return 0;
    }
  • 相关阅读:
    Vue路由机制
    谷歌浏览器打不开应用商店的解决方法
    Vue报错——Component template should contain exactly one root element. If you are using vif on multiple elements, use velseif to chain them instead.
    Vue.js学习之——安装
    Vue使用axios无法读取data的解决办法
    关于localstorage存储JSON对象的问题
    2013年整体计划
    个人喜欢的警语收集
    Linux防火墙的关闭和开启
    Flex修改title 转载
  • 原文地址:https://www.cnblogs.com/Shymuel/p/4393581.html
Copyright © 2011-2022 走看看