线段树,树状数组

线段树的考题,当然其实也可以用树状数组去解决的:

题目:

`One day, little Vasya found himself in a maze consisting of (n + 1) rooms, numbered from 1 to (n + 1). Initially, Vasya is at the first room and to get out of the maze, he needs to get to the (n + 1)-th one.The maze is organized as follows. Each room of the maze has two one-way portals. Let's consider room number i(1 ≤ i ≤ n), someone can use the first portal to move from it to room number (i + 1), also someone can use the second portal to move from it to room number pi, where 1 ≤ pi ≤ i.In order not to get lost, Vasya decided to act as follows.Each time Vasya enters some room, he paints a cross on its ceiling. Initially, Vasya paints a cross at the ceiling of room 1.Let's assume that Vasya is in room i and has already painted a cross on its ceiling. Then, if the ceiling now contains an odd number of crosses, Vasya uses the second portal (it leads to room pi), otherwise Vasya uses the first portal.Help Vasya determine the number of times he needs to use portals to get to room (n + 1) in the end.InputThe first line contains integer n (1 ≤ n ≤ 103) — the number of rooms. The second line contains n integers pi (1 ≤ pi ≤ i). Each pi denotes the number of the room, that someone can reach, if he will use the second portal in the i-th room.OutputPrint a single number — the number of portal moves the boy needs to go out of the maze. As the number can be rather large, print it modulo 1000000007(109 + 7).Sample InputInput21 2Output4Input41 1 2 3Output20Input51 1 1 1 1Output62``这里我用下线段树去做下:

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<utility>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
#include<iterator>
#include<stack>
using namespace std;
#define e tree[id]
#define lson tree[id*2]
#define rson tree[id*2+1]
typedef __int64 LL;
const int INF=1e9+7;
const double eps=1e-7;
const int maxn=100005;
bool f[maxn];
int A[maxn];
struct Tree
{
    int le,ri;
    int sum,d;
}tree[4*maxn];
void pushup(int id){ e.sum=lson.sum+rson.sum; }//取其和
void pushdown(int id)  //延迟更新
{
    if(e.d!=0&&e.le!=e.ri) //d不为0且不是叶子节点
    {
        lson.sum+=(lson.ri-lson.le+1)*e.d; //左右儿子的和要加上他们自身的长度乘以d
        rson.sum+=(rson.ri-rson.le+1)*e.d;
        lson.d+=e.d; //推到下一层,因为子树还没更新
        rson.d+=e.d;
        e.d=0;   //更新完了得置为0,不然会重复更新
    }
}
void Build_tree(int id,int le,int ri)  //建树
{
    e.le=le,e.ri=ri,e.d=0;
    if(le==ri){ e.sum=f[A[le]];return; }
    int mid=(le+ri)/2;
    Build_tree(id*2,le,mid);
    Build_tree(id*2+1,mid+1,ri);
    pushup(id);
}
void Update(int id,int x,int y,int d)  //更新
{
    int le=e.le,ri=e.ri;
    if(x<=le&&ri<=y){ e.sum+=f[e.sum+(ri-le+1)*d];e.d+=d; return; }
    pushdown(id);  //推下去
    int mid=(le+ri)/2;
    if(x<=mid) Update(id*2,x,y,d);   //更新左边
    if(y>mid)  Update(id*2+1,x,y,d); //更新右边
    pushup(id);  //推上去
    return;
}
//void update(int id,int x,int y)  //更新
//{
//    int le=e.le,ri=e.ri;
//    if(le==ri){ e.sum+=y;return;}
//    pushdown(id);  //推下去
//    int mid=(le+ri)/2;
//    if(x<=mid) update(id*2,x,y);   //更新左边
//    else  update(id*2+1,x,y); //更新右边
//    pushup(id);  //推上去
//    return;
//}
void update(int id,int k,int v)  //更新
{
    int le=e.le,ri=e.ri;
    if(le==ri){ e.sum+=v; return; }
    pushdown(id);  //推下去
    int mid=(le+ri)/2;
    if(k<=mid) update(id*2,k,v);   //更新左边
    else update(id*2+1,k,v); //更新右边
    pushup(id);  //推上去
    return;
}
int Query(int id,int x,int y)
{
    int le=e.le,ri=e.ri;
    if(x<=le&&ri<=y) return e.sum;
    pushdown(id);   //这个一定要,不然查询结果会出错
    int mid=(le+ri)/2;
    int ret=0;
    if(x<=mid) ret+=Query(id*2,x,y);
    if(y>mid)  ret+=Query(id*2+1,x,y);
    return ret;
}
bool jug(int a)
{
    while(a)
    {
        if(a%10!=4&&a%10!=7) return 0;
        a/=10;
    }
    return 1;
}
int main()
{


    int N,Q,x,y,d;
    char op[10];
     for(int i=0;i<=10001;i++)
        if(jug(i)) f[i]=1;
        else f[i]=0;
    while(~scanf("%d%d",&N,&Q))
    {
        for(int i=1;i<=N;i++) scanf("%d",&A[i]);
    Build_tree(1,1,N);
    while(Q--)
    {
        scanf("%s",op);
        if(op[0]=='a')
        {
            scanf("%d%d%d",&x,&y,&d);
            for(int i=x;i<=y;i++)
            {
                int x1=f[A[i]];
                A[i]+=d;
                int x2=f[A[i]];
               if(x2==1&&x1==0)update(1,i,1);
               if(x1==1&&x2==0)update(1,i,-1)
                ;
            }
        }
        else
        {
            scanf("%d%d",&x,&y);
            printf("%d\n",Query(1,x,y));
        }
    }
    }
<span style="color: rgb(90, 90, 90); font-family: 'microsoft yahei'; font-size: 18px; line-height: 29.7px; white-space: pre-wrap;">    return 0;</span><br style="color: rgb(90, 90, 90); font-family: 'microsoft yahei'; font-size: 18px; line-height: 29.7px; white-space: pre-wrap;" /><span style="color: rgb(90, 90, 90); font-family: 'microsoft yahei'; font-size: 18px; line-height: 29.7px; white-space: pre-wrap;">}</span>




再来看一篇代码:
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<utility>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
#include<iterator>
#include<stack>
using namespace std;
#define e tree[id]
#define lson tree[id*2]
#define rson tree[id*2+1]
typedef __int64 LL;
const int INF=1e9+7;
const double eps=1e-7;
const int maxn=100005;
bool f[maxn];
int A[maxn];
struct Tree
{
    int le,ri;
    int sum,d;
}tree[4*maxn];
void pushup(int id){ e.sum=lson.sum+rson.sum; }//取其和
void pushdown(int id)  //延迟更新
{
    if(e.d!=0&&e.le!=e.ri) //d不为0且不是叶子节点
    {
        lson.sum+=(lson.ri-lson.le+1)*e.d; //左右儿子的和要加上他们自身的长度乘以d
        rson.sum+=(rson.ri-rson.le+1)*e.d;
        lson.d+=e.d; //推到下一层,因为子树还没更新
        rson.d+=e.d;
        e.d=0;   //更新完了得置为0,不然会重复更新
    }
}
void Build_tree(int id,int le,int ri)  //建树
{
    e.le=le,e.ri=ri,e.d=0;
    if(le==ri){ e.sum=f[A[le]];return; }
    int mid=(le+ri)/2;
    Build_tree(id*2,le,mid);
    Build_tree(id*2+1,mid+1,ri);
    pushup(id);
}
void Update(int id,int x,int y,int d)  //更新
{
    int le=e.le,ri=e.ri;
    if(x<=le&&ri<=y){ e.sum+=f[e.sum+(ri-le+1)*d];e.d+=d; return; }
    pushdown(id);  //推下去
    int mid=(le+ri)/2;
    if(x<=mid) Update(id*2,x,y,d);   //更新左边
    if(y>mid)  Update(id*2+1,x,y,d); //更新右边
    pushup(id);  //推上去
    return;
}
//void update(int id,int x,int y)  //更新
//{
//    int le=e.le,ri=e.ri;
//    if(le==ri){ e.sum+=y;return;}
//    pushdown(id);  //推下去
//    int mid=(le+ri)/2;
//    if(x<=mid) update(id*2,x,y);   //更新左边
//    else  update(id*2+1,x,y); //更新右边
//    pushup(id);  //推上去
//    return;
//}
void update(int id,int k,int v)  //更新
{
    int le=e.le,ri=e.ri;
    if(le==ri){ e.sum+=v; return; }
    pushdown(id);  //推下去
    int mid=(le+ri)/2;
    if(k<=mid) update(id*2,k,v);   //更新左边
    else update(id*2+1,k,v); //更新右边
    pushup(id);  //推上去
    return;
}
int Query(int id,int x,int y)
{
    int le=e.le,ri=e.ri;
    if(x<=le&&ri<=y) return e.sum;
    pushdown(id);   //这个一定要,不然查询结果会出错
    int mid=(le+ri)/2;
    int ret=0;
    if(x<=mid) ret+=Query(id*2,x,y);
    if(y>mid)  ret+=Query(id*2+1,x,y);
    return ret;
}
bool jug(int a)
{
    while(a)
    {
        if(a%10!=4&&a%10!=7) return 0;
        a/=10;
    }
    return 1;
}
int main()
{


    int N,Q,x,y,d;
    char op[10];
     for(int i=0;i<=10001;i++)
        if(jug(i)) f[i]=1;
        else f[i]=0;
    while(~scanf("%d%d",&N,&Q))
    {
        for(int i=1;i<=N;i++) scanf("%d",&A[i]);
    Build_tree(1,1,N);
    while(Q--)
    {
        scanf("%s",op);
        if(op[0]=='a')
        {
            scanf("%d%d%d",&x,&y,&d);
            for(int i=x;i<=y;i++)
            {
                int x1=f[A[i]];
                A[i]+=d;
                int x2=f[A[i]];
               if(x2==1&&x1==0)update(1,i,1);
               if(x1==1&&x2==0)update(1,i,-1)
                ;
            }
        }
        else
        {
            scanf("%d%d",&x,&y);
            printf("%d\n",Query(1,x,y));
        }
    }
    }
    return 0;
}


ra

基于实时迭代的数值鲁棒NMPC双模稳定预测模型(Matlab代码实现)内容概要:本文介绍了基于实时迭代的数值鲁棒非线性模型预测控制(NMPC)双模稳定预测模型的研究与Matlab代码实现,重点在于提升系统在存在不确定性与扰动情况下的控制性能与稳定性。该模型结合实时迭代优化机制,增强了传统NMPC的数值鲁棒性,并通过双模控制策略兼顾动态响应与稳态精度,适用于复杂非线性系统的预测控制问题。文中还列举了多个相关技术方向的应用案例,涵盖电力系统、路径规划、信号处理、机器学习等多个领域,展示了该方法的广泛适用性与工程价值。; 适合人群:具备一定控制理论基础和Matlab编程能力,从事自动化、电气工程、智能制造、机器人控制等领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于非线性系统的高性能预测控制设计,如电力系统调度、无人机控制、机器人轨迹跟踪等;②解决存在模型不确定性、外部扰动下的系统稳定控制问题;③通过Matlab仿真验证控制算法的有效性与鲁棒性,支撑科研论文复现与工程原型开发。; 阅读建议:建议读者结合提供的Matlab代码进行实践,重点关注NMPC的实时迭代机制与双模切换逻辑的设计细节,同时参考文中列举的相关研究方向拓展应用场景,强化对数值鲁棒性与系统稳定性之间平衡的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值