CodeForces 266E More Queries to Array...

本文介绍了一种使用线段树优化的算法,该算法通过建立六个线段树来存储特定形式的数据,使得在O(log n)的时间复杂度内能够快速查询和更新区间值。适用于k值较小的情况,总体复杂度达到O(n log n)。
部署运行你感兴趣的模型镜像

        因为k最大只有5,所以我建六个线段树,分别用于保存ai*i^k的值,这样就能在logn内算出值,所以此题总复杂度nlogn。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
struct Segment
{
    int l;
    int r;
    int mid;
    long long v;
    bool lazy;
    long long tag;
};
Segment tree[6][800000];
long long pi[6][100010];
long long si[6][100010];
long long a[100010];
long long MOD=1000000007;
int pow_mod(int a,int n)
{
    if (n == 0)
        return 1;
    if (n == 1)
        return a;
    int x=pow_mod(a,n/2);
    long long ans=((long long)x*x)%MOD;
    if (n%2 == 1)
        ans=(ans*a)%MOD;
    return (int)ans;
}
void init()
{
    long long i;
    memset(si,0,sizeof(si));
    memset(pi,0,sizeof(pi));
    for(i=0;i<=100000;i++)
    {
        int j;
        for(j=0;j<6;j++)
        {
            int k=j;
            long long tmp=1;
            while(k--)
            tmp=(tmp*i)%MOD;
            pi[j][i]=tmp;
            if(i!=0)
            si[j][i]=(si[j][i-1]+tmp)%MOD;
        }
    }
}
void pushdown(int w,int c)
{
    int t;
    int l,r;
    tree[w][c].lazy=false;
    l=tree[w][c<<1].l;
    r=tree[w][c<<1].r;
    tree[w][c<<1].v=((tree[w][c].tag*(si[w][r]-si[w][l-1]))%MOD+MOD)%MOD;
    tree[w][c<<1].lazy=true;
    tree[w][c<<1].tag=tree[w][c].tag;
    l=tree[w][c<<1|1].l;
    r=tree[w][c<<1|1].r;
    tree[w][c<<1|1].v=((tree[w][c].tag*(si[w][r]-si[w][l-1]))%MOD+MOD)%MOD;
    tree[w][c<<1|1].lazy=true;
    tree[w][c<<1|1].tag=tree[w][c].tag;
}
void build_tree(int w,int c,int l,int r)
{
    int mid;
    mid=(l+r)>>1;
    tree[w][c].l=l;
    tree[w][c].r=r;
    tree[w][c].mid=mid;
    tree[w][c].lazy=false;
    tree[w][c].tag=0;
    if (l == r)
    {
        tree[w][c].v=((a[l]*pi[w][l])%MOD+MOD)%MOD;
        return ;
    }
    build_tree(w,c<<1,l,mid);
    build_tree(w,c<<1|1,mid+1,r);
    tree[w][c].v=((tree[w][c<<1].v+tree[w][c<<1|1].v)%MOD+MOD)%MOD;
}
void update(int w,int c,int l,int r,int x)
{
    //printf("%d %d %d %d %d\n",w,c,l,r,x);
    if (tree[w][c].l == l && tree[w][c].r == r)
    {
        tree[w][c].lazy=true;
        tree[w][c].tag=x;
        tree[w][c].v=((tree[w][c].tag*(si[w][r]-si[w][l-1]))%MOD+MOD)%MOD;
        return ;
    }
    if (tree[w][c].lazy == true)
    {
        pushdown(w,c);
    }
    if (tree[w][c].mid >= r)
    {
        update(w,c<<1,l,r,x);
    }
    else if (tree[w][c].mid < l)
    {
        update(w,c<<1|1,l,r,x);
    }
    else
    {
        update(w,c<<1,l,tree[w][c].mid,x);
        update(w,c<<1|1,tree[w][c].mid+1,r,x);
    }
    tree[w][c].v=((tree[w][c<<1].v+tree[w][c<<1|1].v)%MOD+MOD)%MOD;
}
long long query(int w,int c,int l,int r)
{
    if (tree[w][c].l == l && tree[w][c].r == r)
    {
        return (long long)tree[w][c].v;
    }
    if (tree[w][c].lazy == true)
    {
        pushdown(w,c);
    }
    if (tree[w][c].mid >= r)
    {
        return query(w,c<<1,l,r);
    }
    else if (tree[w][c].mid < l)
    {
        return query(w,c<<1|1,l,r);
    }
    else
    {
        return ((query(w,c<<1,l,tree[w][c].mid)+query(w,c<<1|1,tree[w][c].mid+1,r))%MOD+MOD)%MOD;
    }
}
int getValue(int w,int l,int r,long long x,long long y)
{
    return ((query(w,1,l,r)*(((x*pi[y][l-1])%MOD+MOD)%MOD))%MOD+MOD)%MOD;
}
long long getSum(int k,int l,int r)
{
    long long ans;
    if (k == 0)
    {
        ans=((getValue(0,l,r,1,0))%MOD+MOD)%MOD;
    }
    else if (k == 1)
    {
        ans=((getValue(1,l,r,1,0)-getValue(0,l,r,1,1))%MOD+MOD)%MOD;
    }
    else if (k == 2)
    {
        ans=((((getValue(2,l,r,1,0)-getValue(1,l,r,2,1))%MOD+MOD)%MOD+getValue(0,l,r,1,2))%MOD+MOD)%MOD;
    }
    else if (k == 3)
    {
        ans=((((getValue(3,l,r,1,0)-getValue(2,l,r,3,1))%MOD+MOD)%MOD+((getValue(1,l,r,3,2)-getValue(0,l,r,1,3))%MOD+MOD)%MOD )%MOD+MOD)%MOD;
    }
    else if (k == 4)
    {
        ans=((((((getValue(4,l,r,1,0)-getValue(3,l,r,4,1))%MOD+MOD)%MOD+((getValue(2,l,r,6,2)-getValue(1,l,r,4,3))%MOD+MOD)%MOD)%MOD+MOD)%MOD+getValue(0,l,r,1,4))%MOD+MOD)%MOD;
    }
    else if (k == 5)
    {
        ans=((((((getValue(5,l,r,1,0)-getValue(4,l,r,5,1))%MOD+MOD)%MOD+((getValue(3,l,r,10,2)-getValue(2,l,r,10,3))%MOD+MOD)%MOD)%MOD+MOD)%MOD+((getValue(1,l,r,5,4)-getValue(0,l,r,1,5))%MOD+MOD)%MOD)%MOD+MOD)%MOD;
    }
    return ans;
}
int main()
{
    int n,m,t1,t2,t3,i;
    char o;
    init();
        scanf("%d%d",&n,&m);
    for (i=1; i<=n; i++)
    {
        scanf("%I64d",a+i);
    }
    for (i=0; i<6; i++)
        build_tree(i,1,1,n);
    while (m--)
    {
        scanf("%*c%c%d%d%d",&o,&t1,&t2,&t3);
        if (o == '?')
        {
            printf("%I64d\n",(getSum(t3,t1,t2)%MOD+MOD)%MOD);
        }
        else if (o == '=')
        {
            for (i=0; i<6; i++)
            {
                update(i,1,t1,t2,t3);
            }
        }
    }
    return 0;
}


您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

内容概要:本文提出了一种基于融合鱼鹰算法和柯西变异的改进麻雀优化算法(OCSSA),用于优化变分模态分解(VMD)的参数,进而结合卷积神经网络(CNN)与双向长短期记忆网络(BiLSTM)构建OCSSA-VMD-CNN-BILSTM模型,实现对轴承故障的高【轴承故障诊断】基于融合鱼鹰和柯西变异的麻雀优化算法OCSSA-VMD-CNN-BILSTM轴承诊断研究【西储大学数据】(Matlab代码实现)精度诊断。研究采用西储大学公开的轴承故障数据集进行实验验证,通过优化VMD的模态数和惩罚因子,有效提升了信号分解的准确性与稳定性,随后利用CNN提取故障特征,BiLSTM捕捉时间序列的深层依赖关系,最终实现故障类型的智能识别。该方法在提升故障诊断精度与鲁棒性方面表现出优越性能。; 适合人群:具备一定信号处理、机器学习基础,从事机械故障诊断、智能运维、工业大数据分析等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①解决传统VMD参数依赖人工经验选取的问题,实现参数自适应优化;②提升复杂工况下滚动轴承早期故障的识别准确率;③为智能制造与预测性维护提供可靠的技术支持。; 阅读建议:建议读者结合Matlab代码实现过程,深入理解OCSSA优化机制、VMD信号分解流程以及CNN-BiLSTM网络架构的设计逻辑,重点关注参数优化与故障分类的联动关系,并可通过更换数据集进一步验证模型泛化能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值