ACdream 1101 线段树维护LCIS

本文介绍如何使用线段树来维护最长连续递增子序列(LCIS),重点在于线段树的Merge操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线段树维护LCIS  主要是Merge操作

#include<bits/stdc++.h>
#define Mem(a,b) memset(a,b,sizeof(a))
#define lson root<<1
#define rson root<<1|1
#define Mid int mid=(l+r)>>1
#define N 100100
using namespace std;
struct segtree {
    int l,r,lcis,lenl,lenr;//左值,右值,左连续,右连续
};
segtree ans[N<<2];
int lazy[N<<2],ql,qr,val,res,resr,reslenr;
void pushdown(int root,int l,int r) {
    if(lazy[root]) {
        lazy[lson]=lazy[rson]=lazy[root];
        ans[lson].lcis=ans[lson].lenl=ans[lson].lenr=1;
        ans[lson].l=ans[lson].r=lazy[lson];
        ans[rson].lcis=ans[rson].lenl=ans[rson].lenr=1;
        ans[rson].l=ans[rson].r=lazy[rson];
        lazy[root]=0;
    }//这里还可以携程一个函数的形式
}
void Merge(int root,int l,int r) {//LICS的合并
    ans[root].l=ans[lson].l;
    ans[root].r=ans[rson].r;
    ans[root].lcis=max(ans[lson].lcis,ans[rson].lcis);
    ans[root].lenl=ans[lson].lenl;
    ans[root].lenr=ans[rson].lenr;
    Mid;
    if(ans[lson].r<ans[rson].l) {
        if(ans[lson].lenr+ans[rson].lenl>ans[root].lcis)
            ans[root].lcis=ans[lson].lenr+ans[rson].lenl;
        if(ans[lson].lenl==mid-l+1)
            ans[root].lenl+=ans[rson].lenl;
        if(ans[rson].lenr==r-mid)
            ans[root].lenr+=ans[lson].lenr;
    }
}
void build(int root,int l,int r) {
    if(l==r) {
        int x;
        scanf("%d",&x);
        ans[root].lcis=ans[root].lenl=ans[root].lenr=1;
        ans[root].l=ans[root].r=x;
        //printf("%d %d %d %d %d %d %d\n",l,r,ans[root].l,ans[root].r,ans[root].lcis,ans[root].lenl,ans[root].lenr);
        return ;
    }
    Mid;
    build(lson,l,mid);
    build(rson,mid+1,r);
    Merge(root,l,r);

}
void query(int root,int l,int r) {
    if(l>qr||r<ql)
        return ;
    if(l>=ql&&r<=qr) {
        if(res==0) {
            res=ans[root].lcis;
            resr=ans[root].r;
            reslenr=ans[root].lenr;
            return ;
        }
        res=max(ans[root].lcis,res);
        if(resr<ans[root].l) {
            res=max(res,reslenr+ans[root].lenl);
            if(ans[root].lenr==r-l+1)
                reslenr+=ans[root].lenr;
            else
                reslenr=ans[root].lenr;
        } else {
            reslenr=ans[root].lenr;
        }
        resr=ans[root].r;

        return;
    }
    pushdown(root,l,r);
    Mid;
    query(lson,l,mid);
    query(rson,mid+1,r);
    Merge(root,l,r);
}
void update(int root,int l,int r) {
    if(l>qr||r<ql)
        return ;
    if(l>=ql&&r<=qr) {
        lazy[root]=val;
        ans[root].l=ans[root].r=val;
        ans[root].lcis=ans[root].lenl=ans[root].lenr=1;
        return;
    }
    pushdown(root,l,r);
    Mid;
    update(lson,l,mid);
    update(rson,mid+1,r);
    Merge(root,l,r);
}
int main() {
    //freopen("in.txt","r",stdin);
    int n,m;
    scanf("%d%d",&n,&m);
    Mem(lazy,0);
    build(1,1,n);
    for(int i=1; i<=m; i++) {
        char type;
        scanf("\n%c",&type);
        if(type=='Q') {
            scanf("%d%d",&ql,&qr);
            res=0;
            query(1,1,n);
            printf("%d\n",res);
        } else {
            scanf("%d%d%d",&ql,&qr,&val);
            update(1,1,n);
        }
    }
}

基于html+python+Apriori 算法、SVD(奇异值分解)的电影推荐算法+源码+项目文档+算法解析+数据集,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档 电影推荐算法:Apriori 算法、SVD(奇异值分解)推荐算法 电影、用户可视化 电影、用户管理 数据统计 SVD 推荐 根据电影打分进行推荐 使用 svd 模型计算用户对未评分的电影打分,返回前 n 个打分最高的电影作为推荐结果 n = 30 for now 使用相似电影进行推荐 根据用户最喜欢的前 K 部电影,分别计算这 K 部电影的相似电影 n 部,返回 K*n 部电影进行推荐 K = 10 and n = 5 for now 根据相似用户进行推荐 获取相似用户 K 个,分别取这 K 个用户的最喜爱电影 n 部,返回 K*n 部电影进行推荐 K = 10 and n = 5 for now Redis 使用 Redis 做页面访问次数统计 缓存相似电影 在使用相似电影推荐的方式时,每次请求大概需要 6.6s(需要遍历计算与所有电影的相似度)。 将相似电影存储至 redis 中(仅存储 movie_id,拿到 movie_id 后还是从 mysql 中获取电影详细信息), 时间缩短至:93ms。 十部电影,每部存 top 5 similar movie 登录了 1-6 user并使用了推荐系统,redis 中新增了 50 部电影的 similar movie,也就是说,系统只为 6 为用户计算了共 60 部电影的相似度,其中就有10 部重复电影。 热点电影重复度还是比较高的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值