第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-8 算法训练 操作格子 线段树

简介: 第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-8 算法训练 操作格子 线段树

第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-8 算法训练 操作格子 线段树


前言

       最近的一些文章都可能会很碎,写到哪里是哪里,过一阵子会具体的整理一遍,这里其它的类型题先往后排一排,因为蓝桥最后考的也就是对题目逻辑的理解能力,也就是dp分析能力了,所以就主要目标定在这里,最近的题目会很散,很多,基本上都是网罗全网的一些dp练习题进行二次训练,准备比赛的学生底子薄的先不建议看啊,当然,脑子快的例外,可以直接跳过之前的一切直接来看即可,只需要你在高中的时候数学成绩还可以那就没啥问题,其实,dp就是规律总结,我们只需要推导出对应题目的数学规律就可以直接操作,可能是一维数组,也可能是二维数组,总体来看二维数组的较多,但是如果能降为的话建议降为,因为如果降为起来你看看时间复杂度就知道咋回事了,那么在这里祝大家能无序的各种看明白,争取能帮助到大家。


算法训练 操作格子

资源限制

内存限制:256.0MB   C/C++时间限制:1.0s   Java时间限制:3.0s   Python时间限制:5.0s

问题描述

有n个格子,从左到右放成一排,编号为1-n。

共有m次操作,有3种操作类型:

1.修改一个格子的权值,

2.求连续一段格子权值和,

3.求连续一段格子的最大值。

对于每个2、3操作输出你所求出的结果。

输入格式

第一行2个整数n,m。

接下来一行n个整数表示n个格子的初始权值。

接下来m行,每行3个整数p,x,y,p表示操作类型,p=1时表示修改格子x的权值为y,p=2时表示求区间[x,y]内格子权值和,p=3时表示求区间[x,y]内格子最大的权值。

输出格式

有若干行,行数等于p=2或3的操作总数。

每行1个整数,对应了每个p=2或3操作的结果。

样例输入

4 3

1 2 3 4

2 1 3

1 4 3

3 1 4

样例输出

6

3

数据规模与约定

对于20%的数据n <= 100,m <= 200。

对于50%的数据n <= 5000,m <= 5000。

对于100%的数据1 <= n <= 100000,m <= 100000,0 <= 格子权值 <= 10000

题解:

C语言

#include <stdio.h>  
#define N 100000  
#define A 1000  
#define B 100  
int sum(int* a, int m, int n)  
{  
   int i,s=0;  
   for (i=m;i<=n;i++)  
       s+=a[i];  
   return s;  
}  
int max(int* a, int m, int n)  
{  
   int i,s=a[m];  
   for (i=m+1;i<=n;i++)  
       if (s<a[i])  
           s=a[i];  
   return s;  
}  
int main()  
{  
   int i,j,k,m,n;  
   int a[100000],b[100000][3],c[A][2]={0};  
   scanf("%d%d",&n,&m);  
   for (i=0; i<n;i++)  
       scanf("%d",&a[i]);  
   for (i=0;i<m;i++)  
       for (j=0;j<3;j++)  
           scanf("%d", &b[i][j]);  
   for (i=0;i<(n+B-1)/B;i++)  
   {  
       c[i][0]=c[i][1]=a[i * B];  
       for (j=i*B+1;j<i*B+B && j<n;j++)  
       {  
           c[i][0]+=a[j];  
           if (c[i][1]<a[j])  
               c[i][1]=a[j];  
       }  
   }  
   for (i=0;i<m;i++)  
   {  
       if (b[i][0]==1)  
       {  
           c[(b[i][1]-1)/B][0]+=b[i][2]-a[b[i][1]-1];  
           k=(b[i][1]-1)/B;  
           if (c[k][1]<=b[i][2])  
           {  
               c[k][1]=b[i][2];  
           }  
           else if (a[b[i][1]-1]==c[k][1])  
           {  
               a[b[i][1]-1]=b[i][2];  
               c[k][1]=max(a,k*B,k*B+B>n ? n-1 : k*B+B-1);  
           }  
           a[b[i][1]-1]=b[i][2];  
       }  
       else if(b[i][0]==2)  
       {  
           int s=0;  
           b[i][1]--, b[i][2]--;  
           int o=b[i][2]/B-b[i][1]/B;  
           if (o<2)  
           {  
               s=sum(a,b[i][1],b[i][2]);  
           }  
           else  
           {  
               s=sum(a,b[i][1],(b[i][1]+B)/B*B-1);  
               s+=sum(a, b[i][2]/B*B, b[i][2]);  
               for (j = b[i][1]/B+1;j<b[i][2]/B;j++)  
                   s += c[j][0];  
           }  
           printf("%d\n",s);  
       }  
       else if (b[i][0]==3)  
       {  
           int s = 0,t;  
           b[i][1]--, b[i][2]--;  
           int o=b[i][2]/B-b[i][1]/B;  
           if (o<2)  
           {  
               s=max(a, b[i][1],b[i][2]);  
           }  
           else  
           {  
               s=max(a,b[i][1],(b[i][1]+B)/B*B-1);  
               t=max(a,b[i][2]/B*B,b[i][2]);  
               if (s<t)s=t;  
               for (j=b[i][1]/B+1;j<b[i][2]/B;j++)  
                   if (s<c[j][1])  
                       s=c[j][1];  
           }  
           printf("%d\n",s);  
       }  
   }  
   return 0;  
}

C++语言

#include <cstdio>
#include <algorithm>
struct Tree
{
    int sum, max;
};
Tree tree[1 << 18];
void scan(int &n)
{
    char c;
    
    c = getchar();
    if (c == EOF) {
        return ;
    }
    while (c < '0' || c > '9') {
        c = getchar();
    }
    n = c - '0';
    while (c = getchar(), c >= '0' && c <= '9') {
        n *= 10;
        n += c - '0';
    }
}
void put(int n)
{
    int cnt = 0;
    char s[16];
    
    if (n == 0) {
        putchar('0');
        return ;
    }
    for( ; n; n /= 10) {
        s[cnt++] = n % 10 + '0';
    }
    while (cnt--) {
        putchar(s[cnt]);
    }
}
void update(int n, int v)
{
    for (n += (1 << 17),tree[n].sum = tree[n].max = v, n >>= 1; n; n >>= 1) {
        tree[n].max = std::max(tree[n + n].max, tree[n + n + 1].max);
        tree[n].sum = tree[n + n].sum + tree[n + n + 1].sum;
    }
}
int query(int s, int t, int func)
{
    int sum = 0, max = 0;
    
    for (s += (1 << 17) - 1, t += (1 << 17) + 1; s ^ t ^ 1; s >>= 1, t >>= 1) {
        if (~s & 1) {
            sum += tree[s ^ 1].sum;
            max = std::max(max, tree[s ^ 1].max);
        }
        if (t & 1) {
            sum += tree[t ^ 1].sum;
            max = std::max(max, tree[t ^ 1].max);
        }
    }
    return func ? max : sum;
}
int main()
{
    int n, m, i, a, b, c;
    
    scan(n);scan(m);
    for (i = 1; i <= n; ++i) {
        scan(a);
        update(i, a);
    }
    while (m--) {
        scan(c);scan(a);scan(b);
        c == 1 && (update(a, b), 0);
        c == 2 && (put(query(a, b, 0)), putchar('\n'), 0);
        c == 3 && (put(query(a, b, 1)), putchar('\n'), 0);
    }
    return 0;
}

Java语言

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Main {
  
  static int[] array;
  
  static long []mark;
  
  static long []Tree;
  
  static int[] Max;
  public static void main(String[] args) throws IOException {
    // TODO Auto-generated method stub
    StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    
    PrintWriter pt=new PrintWriter(System.out);
    
    st.nextToken();
    
    int n=(int)st.nval;
    
    array=new int[n+1];//图方便从1开始
    
    mark=new long[4*n+4];
    
    Tree=new long[4*n+4];
    
    Max=new int[4*n+4];
    
    st.nextToken();
    int m=(int)st.nval;
    
    for(int i=1;i<=n;i++) {
      st.nextToken();
      array[i]=(int)st.nval;
    }
    
    build(1,n,1);
    
    for(int i=0;i<m;i++) {
      st.nextToken();
      if((int)st.nval==1) {
        st.nextToken();
        int a=(int)st.nval;
        st.nextToken();
        int v=(int)st.nval;
        
        update(a,a,v,1,1,n);
      }
      else if((int)st.nval==2){
        st.nextToken();
        int a=(int)st.nval;
        st.nextToken();
        int b=(int)st.nval;
        pt.println(query(a, b, 1, 1, n));
      }
      else {
        st.nextToken();
        int a=(int)st.nval;
        st.nextToken();
        int b=(int)st.nval;
        pt.println(getMax(a, b, 1, 1, n));
      }
    }
    pt.close();
    
    
    
  }
  
  
  public static void build(int l,int r,int p) {
    
    
    if(l==r) {
      Tree[p]=array[l];
      Max[p]=array[l];
    }
    else {
      int mid=l+(r-l)/2;
      build(l,mid,p*2);
      build(mid+1,r,p*2+1);
      Tree[p]=Tree[p*2]+Tree[p*2+1];
      Max[p]=Math.max(Max[p*2], Max[p*2+1]);
          
    }
    
  }
  
  
  public static void update(int l,int r,int d,int p,int nowL,int nowR) {
    
    if(r<nowL||l>nowR)
      return;
    if(l<=nowL&&r>=nowR) {
      Tree[p]=d;//懒标记的规则就是在更新当前的mark之前 已经修改了当前的tree的值
        Max[p]=d;
    }
    else {
      
      int mid=nowL+(nowR-nowL)/2;
      update(l,r,d,p*2,nowL,mid);
      update(l,r,d,p*2+1,mid+1,nowR);
      Tree[p]=Tree[p*2]+Tree[p*2+1];
      Max[p]=Math.max(Max[p*2], Max[p*2+1]);
      
    }
      
  }
  
  public static long query(int l,int r,int p,int cl,int cr) {
    
     if (cl> r || cr < l)
            return 0;
        else if (cl >= l && cr <= r)
            return Tree[p];
        else
        {
            int mid =cl+(cr-cl)/2;
            return query(l, r, p * 2, cl, mid) + query(l, r, p * 2 + 1, mid + 1, cr ); 
            // 上一行拆成三行写就和区间修改格式一致了
        }
  }
  
  public static int getMax(int l,int r,int p,int cl,int cr) {
    
    if(cl>r||l>cr) {
      return 0;
    }
    if(cl>=l&&cr<=r)
      return Max[p];
    
    int mid=cl+(cr-cl)/2;
    
    return Math.max(getMax(l,r,p*2,cl,mid),getMax(l,r,p*2+1,mid+1,cr));
  }
  
  
  
}

Python语言

n,m = map(int,input().split())
value = list(map(int,input().split()))
num = []
a = [ dict() for j in range(4*n)]
# print(a)
def update(k):
    node = a[k]
    node['sum'] = a[k * 2]['sum'] + a[k * 2 + 1]['sum']
    node['max'] = max(a[k * 2]['max'], a[k * 2 + 1]['max'])
def built(k,l,r):
    node = a[k]
    node['l'] = l
    node['r'] = r
    if l == r:
        node['sum'] = value[l]
        node['max'] = value[l]
    else:
        mod = int((r+l)/2)
        built(2*k,l,mod)
        built(2*k+1,mod+1,r)
        update(k)
def chang(k,x,y):
    node = a[k]
    if node['l']==node['r']:
        node['sum'] = y
        node['max'] = y
    else:
        mod = int((node['r']+node['l'])/2)
        if x>mod:
            chang(k*2+1,x,y)
        else:
            chang(k*2,x,y)
        update(k)
def Sum(k,l,r):
    node = a[k]
    if node['l']==l and node['r']==r:
        return node['sum']
    else:
        mod = int((node['r']+node['l'])/2)
        if r<=mod:
            return Sum(k*2,l,r)
        elif l>mod:
            return Sum(k*2+1,l,r)
        else:
            return Sum(k*2,l,mod)+Sum(k*2+1,mod+1,r)
def Max(k,l,r):
    node = a[k]
    if node['l'] == l and node['r'] == r:
        return node['max']
    else:
        mod = int((node['r'] + node['l']) / 2)
        if r <= mod:
            return Max(k * 2, l, r)
        elif l > mod:
            return Max(k * 2+1, l, r)
        else:
            return max(Max(k * 2, l, mod),Max(k * 2 + 1, mod + 1, r))
built(1,0,n-1)
for i in range(m):
    p,x,y = map(int,input().split())
    if p == 1:
        chang(1,x-1,y)
    if p == 2:
        s=Sum(1,x-1,y-1)
        num.append(s)
    if p == 3:
        m = Max(1,x-1,y-1)
        num.append(m)
for i in num:
    print(i)

没有什么不付出就能拿到的结果,我们都是在负重前行,最终结果与自身先天的脑力有一定的关系,但是还是有很大一部分看自己后天的努力,其实从报名到比赛也就5个月左右,真正刷题的事件也就2个月,2个月回忆一下你真正的认真刷过题吗,如果你真的用尽所有的精力去努力了,那么我相信你最终的成绩一定会让你满意的,加油。


相关文章
|
1月前
|
Python
蓝桥杯练习题(一):Python组之入门训练题
这篇文章是关于蓝桥杯Python组的入门训练题,包括Fibonacci数列、圆的面积、序列求和和A+B问题的具体代码实现和样例输出。
120 0
|
1月前
|
存储 机器学习/深度学习 算法
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
蓝桥杯Python编程练习题的集合,涵盖了从基础到提高的多个算法题目及其解答。
60 3
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
|
19天前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
1月前
|
机器学习/深度学习 算法 决策智能
【机器学习】揭秘深度学习优化算法:加速训练与提升性能
【机器学习】揭秘深度学习优化算法:加速训练与提升性能
|
1月前
|
算法 Java C++
【贪心算法】算法训练 ALGO-1003 礼物(C/C++)
【贪心算法】算法训练 ALGO-1003 礼物(C/C++)
【贪心算法】算法训练 ALGO-1003 礼物(C/C++)
|
1月前
|
算法 Java 程序员
【算法每日一练及解题思路】有n级台阶,一次只能上1级或2级,共有多少种走法?
本文深入解析了“爬楼梯问题”,探讨了递归与迭代两种解法,并提供了Java代码实现。通过分析问题本质,帮助读者理解动态规划技巧,提高解决实际编程问题的能力。关键词:Java, 算法, 动态规划, 爬楼梯问题, 递归, 迭代。
67 0
|
1月前
|
算法 C++
【算法解题思想】动态规划+深度优先搜索(C/C++)
【算法解题思想】动态规划+深度优先搜索(C/C++)
|
1月前
|
算法 C++
蓝桥 算法训练 共线(C++)
蓝桥 算法训练 共线(C++)
|
4月前
knn增强数据训练
【7月更文挑战第27天】
36 10
|
4月前
|
数据采集 编解码 人工智能
破解ChatGPT惊人耗电!DeepMind新算法训练提效13倍,能耗暴降10倍
【7月更文挑战第19天】DeepMind的JEST算法革新AI训练,提升效率13倍,节能10倍。通过联合数据批次选择,预训练指导及多分辨率训练,优化资源利用,降低能耗。实验显示性能提升,达到SOTA水平,但实施需大量资源,依赖优质参考模型。[论文链接](https://arxiv.org/pdf/2406.17711)
69 10