算法整理

线段树模板

#include<cstdio>
#define N 200100
int n,Q,tot=0,x;
long long a[200100];
struct tree
{
    int left,right;
    int rptr,lptr;
    long long sum;
    long long bj;
}t[N*4];
void buildtree(int ll,int rr)
{
    int cur=++tot;
    t[cur].left=ll;
    t[cur].right=rr;
    if (ll+1!=rr)
      {
           t[cur].lptr=tot+1;
           buildtree(ll,(ll+rr)/2);
           t[cur].rptr=tot+1;
           buildtree((ll+rr)/2,rr);
           t[cur].sum=t[t[cur].lptr].sum+t[t[cur].rptr].sum;
      }
    else t[cur].sum=a[ll];
}
void update(long long k)
{
    t[t[k].lptr].sum+=(t[t[k].lptr].right-t[t[k].lptr].left)*t[k].bj;
    t[t[k].rptr].sum+=(t[t[k].rptr].right-t[t[k].rptr].left)*t[k].bj;
    t[t[k].lptr].bj+=t[k].bj;
    t[t[k].rptr].bj+=t[k].bj;
    t[k].bj=0;
}
void change(int k,int ll,int rr,long long delta)
{
    if (ll<=t[k].left&&rr>=t[k].right)
      {
          t[k].sum+=(t[k].right-t[k].left)*delta;
          t[k].bj+=delta;
      }
    else
      {
          if (t[k].bj) update(k);
          if (ll<(t[k].left+t[k].right)/2)
            change(t[k].lptr,ll,rr,delta);
          if (rr>(t[k].left+t[k].right)/2)
            change(t[k].rptr,ll,rr,delta);
          t[k].sum=t[t[k].lptr].sum+t[t[k].rptr].sum;
      }
}
long long find(int  k,int ll,int rr)
{
    if (ll<=t[k].left&&rr>=t[k].right)
       return t[k].sum;
    long long ans=0;
    if (t[k].bj) update(k);
    if (ll<(t[k].left+t[k].right)/2)
      ans+=find(t[k].lptr,ll,rr);
    if (rr>(t[k].left+t[k].right)/2)
      ans+=find(t[k].rptr,ll,rr);
    return ans;
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
      scanf("%lld",&a[i]);
    buildtree(1,n+1);//注意由于区间是左闭右开,所以右边的数加一,下同
    scanf("%d",&Q);
    for (int i=1;i<=Q;i++)
      {
           int f;
           scanf("%d",&f);
           if (f==1)
             {
                   int a,b;
                   scanf("%d%d%lld",&a,&b,&x);
                change(1,a,b+1,x);
           }
        else
          {
               int a,b;
               scanf("%d%d",&a,&b);
               printf("%lld\n",find(1,a,b+1));//别忘了换行
          }
      }
    return 0;
}
时间: 2024-10-08 19:35:06

算法整理的相关文章

最短路径算法整理(二)

本文是最短路径算法整理的第二篇,想阅读第一篇的朋友能够点击下面链接: http://blog.csdn.net/hjd_love_zzt/article/details/26739593 这一篇博客继续以一些OJ上的题目为载体,整理一下最短路径算法.会陆续的更新... 1.HDU 2544 题目与分析:这道题抽象一下,还是:"求a到b的最短路径"..所须要的基本条件是:点数.边数.起点.终点 下面给出floyd.dijkstra.bellmanford三种最短路径算法关于这道题的解法:

算法整理(三):插入排序

插入排序很简单,就像打扑克.手里有个牌4,再来一张牌5就本能的放到第一个牌的右边.如果来了个3就从右往左扫描,只要左边的比这个待插入数字大就交换. 插入排序是一种稳定的排序方法,时间复杂度O(n*n),空间复杂度O(1),最好的情况下时间复杂度为O(1).即本来就是一个有序或者相等的数组,则只需比较n-1次即可.下为源码,只需三行代码即可. //============================================================================

常见数据结构与算法整理总结(上)

数据结构是以某种形式将数据组织在一起的集合,它不仅存储数据,还支持访问和处理数据的操作.算法是为求解一个问题需要遵循的.被清楚指定的简单指令的集合.下面是自己整理的常用数据结构与算法相关内容,如有错误,欢迎指出. 为了便于描述,文中涉及到的代码部分都是用Java语言编写的,其实Java本身对常见的几种数据结构,线性表.栈.队列等都提供了较好的实现,就是我们经常用到的Java集合框架,有需要的可以阅读这篇文章.Java - 集合框架完全解析 一.线性表 1.数组实现 2.链表 二.栈与队列 三.树

算法整理(四):浅析快速排序的优化问题

前文介绍了快速排序的单边扫描和双边扫描,但么有做对比,今天来简单分析下. 一.单边扫描的缺点 单边扫描最大的缺点是每次都要交换,如果一个数组是 5 4 3 2 1,用单边扫描的话,则从4开始,4要和4交换一次,3要和3交换一次,依次类推,这种无意义的操作.正因此用双边扫描会更好,第一趟只需交换一次,就能得到1 4 3 2 5这样的数组.但双边扫描也是可以进一步优化的. 二.双边扫描的优化 优化一:对key值得选取应该使用随机选取的原则,而非第一个数字.意义大家都懂得. 优化二:前文的方法是挖坑法

算法整理(二)---快速排序的两种实现方式:双边扫描和单边扫描

首先简单谈下快速排序的特点,时间复杂度O(nLog n),最差时间复杂度O(n^2),平均时间O(nLog n).因为用到了函数栈,空间复杂度为O(lg n),最差为O(n).是一种不稳定的排序方法.基本思想是分治法,这位大大的http://blog.csdn.net/morewindows/article/details/6684558 讲的非常清楚了,分治法+挖坑法,我就不多说了.就是以某个数为参照,使得左边的都小于他,右边的数都大于他.然后对他的左右两个区间采取同样的方法进行递归. 就其整

[ACM] 最短路算法整理(bellman_ford , SPFA , floyed , dijkstra 思想,步骤及模板)

以杭电2544题目为例 最短路 Problem Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据.每组数据第一行是两个整数N.M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路.N=M=0

算法整理(二)---高速排序的两种实现方式:双边扫描和单边扫描

首先简单谈下高速排序的特点,时间复杂度O(nLog n),最差时间复杂度O(n^2),平均时间O(nLog n).由于用到了函数栈,空间复杂度为O(lg n),最差为O(n).是一种不稳定的排序方法.基本思想是分治法,这位大大的http://blog.csdn.net/morewindows/article/details/6684558 讲的很清楚了,分治法+挖坑法,我就不多说了.就是以某个数为參照,使得左边的都小于他,右边的数都大于他.然后对他的左右两个区间採取相同的方法进行递归. 就其总体

常见数据结构与算法整理总结(下)

这篇文章是常见数据结构与算法整理总结的下篇,上一篇主要是对常见的数据结构进行集中总结,这篇主要是总结一些常见的算法相关内容,文章中如有错误,欢迎指出. 一.概述 二.查找算法 三.排序算法 四.其它算法 五.常见算法题 六.总结 一.概述 以前看到这样一句话,语言只是工具,算法才是程序设计的灵魂.的确,算法在计算机科学中的地位真的很重要,在很多大公司的笔试面试中,算法掌握程度的考察都占据了很大一部分.不管是为了面试还是自身编程能力的提升,花时间去研究常见的算法还是很有必要的.下面是自己对于算法这

算法整理之动态规划

我现在介绍的这个版本,是从算法爱好者中看到的一个别人的漫画版本.题目:有一座高度是10级台阶的楼梯,从下往上走,每跨一步只能向上1级或者2级台阶.要求用程序来求出一共有多少种走法.比如,每次走1级台阶,一共走10步,这是其中一种走法.我们可以简写成 1,1,1,1,1,1,1,1,1,1.再比如,每次走2级台阶,一共走5步,这是另一种走法.我们可以简写成 2,2,2,2,2. 分析:这种问题是典型的使用动态规划解决的问题,在使用动态规划的方法之前,能想到的方法可能就是使用排列组合,这是一个非常复

JS 排序算法整理

关于排序算法的问题可以在网上搜到一大堆,但是纯 JS 版比较零散,之前面试的时候特意整理了一遍,附带排序效率比较. //1.冒泡排序 var bubbleSort = function(arr) { for (var i = 0, len = arr.length; i < len - 1; i++) { for (var j = i + 1; j < len; j++) { if (arr[i] > arr[j]) { var temp = arr[i]; arr[i] = arr[j