zoukankan      html  css  js  c++  java
  • 【题解】洛谷P1198 [JSOI2008] 最大数(线段树)

    洛谷P1198:https://www.luogu.org/problemnew/show/P1198

    思路

    一道水水的线段树 20分钟A掉

    这道题只涉及到单点修改和区间查询 所以这道题甚至不用Lazy-Tag

    每次加入一个新的点就是修改一个节点

    总区间长为操作次数m (假设所有操作都为添加一个节点)

    因此题目就简单多了

    代码

    #include<iostream>
    using namespace std;
    #define ll long long
    #define Max 200000
    #define INF 1e9+7
    ll m,p,n,t;
    ll maxn[Max<<2];//4倍数组 
    void build(ll s,ll v,ll l,ll r,ll k)
    {
        if(l==r)
        {
            maxn[k]=v;//叶子节点 
            return;
        }
        ll mid=(l+r)>>1;
        if(mid>=s) build(s,v,l,mid,k<<1);//当此点在mid前 只需要建mid前面的树 
        if(mid<s) build(s,v,mid+1,r,k<<1|1);//同上 
        maxn[k]=max(maxn[k<<1],maxn[k<<1|1])%p;
        return;
    }
    ll query(ll x,ll y,ll l,ll r,ll k)
    {
        if(l>=x&&r<=y) return maxn[k]%p;
        ll mid=(l+r)>>1;
        ll a1=-INF,b1=-INF;//因为有负数 所以要设一个负的极小值 
        if(x<=mid) a1=query(x,y,l,mid,k<<1)%p;//左子树的最大值 
        if(y>mid) b1=query(x,y,mid+1,r,k<<1|1)%p;//右子树的最大值 
        return max(a1,b1);//选一个最大的 
    }
    int main()
    {
        cin>>m>>p;
        for(ll i=1;i<=m;i++)
        {
            char a;
            ll b;
            cin>>a>>b;
            if(a=='A')
            {
                n++;
                build(n,(b+t)%p,1,m,1);//n为当前是第几个节点 注意叠加t 
            }
            if(a=='Q')
            {
                t=query(n-b+1,n,1,m,1);//注意区间是[n-b+1,n] 因为是倒数的b个数 
                cout<<t<<endl;
            }
        }
    }
    View Code
  • 相关阅读:
    java 备忘
    C++ 命名规范 (转)
    代码格式规范
    using namespace 由来
    结构体数组 初始化(转)
    Java Servlet系列之Servlet生命周期
    进程,内存,管理 ps,pstree,top,free,vmstat,iftop,lsof,查看网速
    网络基础知识-
    进程作业管理2-kill,前后台作业,并行执行
    计划任务cron,date,时间同步ntp,chrony
  • 原文地址:https://www.cnblogs.com/BrokenString/p/9762192.html
Copyright © 2011-2022 走看看