[Dr.Lib]Note:Algorithms – Segment Tree 线段树

Via http://en.wikipedia.org/wiki/Segment_tree

In computer science, a segment tree is a tree data structure for storing intervals, or segments. It allows querying which of the stored segments contain a given point. It is, in principle, a static structure; that is, its content cannot be modified once the structure is built. A similar data structure is the interval tree.

A segment tree for a set I of n intervals uses O(n log n) storage and can be built in O(n log n) time. Segment trees support searching for all the intervals that contain a query point in O(log n + k), k being the number of retrieved intervals or segments.

Applications of the segment tree are in the areas of computational geometry, and geographic information systems.

The segment tree can be generalized to higher dimension spaces as well.

 

 

Graphic example of the structure of the segment tree. This instance is built for the segments shown at the bottom.
 

继续阅读

[Dr.Lib]Note:Algorithms – Binary Indexed Tree 树状数组

Via http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=binaryIndexedTrees

Introduction

We often need some sort of data structure to make our algorithms faster. In this article we will discuss the Binary Indexed Trees structure. According to Peter M. Fenwick, this structure was first used for data compression. Now it is often used for storing frequencies and manipulating cumulative frequency tables.

Let's define the following problem: We have n boxes. Possible queries are
1. add marble to box i
2. sum marbles from box k to box l

The naive solution has time complexity of O(1) for query 1 and O(n) for query 2. Suppose we make m queries. The worst case (when all queries are 2) has time complexity O(n * m). Using some data structure (i.e. RMQ) we can solve this problem with the worst case time complexity of O(m log n). Another approach is to use Binary Indexed Tree data structure, also with the worst time complexity O(m log n) — but Binary Indexed Trees are much easier to code, and require less memory space, than RMQ.

 

Notation


  BIT – Binary Indexed Tree
  MaxVal – maximum value which will have non-zero frequency
  f[i] – frequency of value with index i, i = 1 .. MaxVal
  c[i] – cumulative frequency for index i (f[1] + f[2] + … + f[i])
  tree[i] – sum of frequencies stored in BIT with index i (latter will be described what index means); sometimes we will write tree frequency instead sum of frequencies stored in BIT
  num¯ – complement of integer num (integer where each binary digit is inverted: 0 -> 1; 1 -> 0 )
NOTE: Often we put f[0] = 0, c[0] = 0, tree[0] = 0, so sometimes I will just ignore index 0.
 

Basic idea


Each integer can be represented as sum of powers of two. In the same way, cumulative frequency can be represented as sum of sets of subfrequencies. In our case, each set contains some successive number of non-overlapping frequencies.

idx is some index of BIT. r is a position in idx of the last digit 1 (from left to right) in binary notation. tree[idx] is sum of frequencies from index (idx – 2^r + 1) to index idx (look at the Table 1.1 for clarification). We also write that idx is responsible for indexes from (idx – 2^r + 1) to idx (note that responsibility is the key in our algorithm and is the way of manipulating the tree).

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
f 1 0 2 1 1 3 0 4 2 5 2 2 3 1 0 2
c 1 1 3 4 5 8 8 12 14 19 21 23 26 27 27 29
tree 1 1 2 4 1 4 0 12 2 7 2 11 3 4 0 29

Table 1.1

 

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
tree 1 1..2 3 1..4 5 5..6 7 1..8 9 9..10 11 9..12 13 13..14 15 1..16

Table 1.2 – table of responsibility


Image 1.3 – tree of responsibility for indexes (bar shows range of frequencies accumulated in top element)

Image 1.4 – tree with tree frequencies

 

Suppose we are looking for cumulative frequency of index 13 (for the first 13 elements). In binary notation, 13 is equal to 1101. Accordingly, we will calculate c[1101] = tree[1101] + tree[1100] + tree[1000] (more about this later).

Isolating the last digit
NOTE: Instead of "the last non-zero digit," it will write only "the last digit."

There are times when we need to get just the last digit from a binary number, so we need an efficient way to do that. Let num be the integer whose last digit we want to isolate. In binary notation num can be represented as a1b, where a represents binary digits before the last digit and b represents zeroes after the last digit.

Integer -num is equal to (a1b)¯ + 1 = a¯0b¯ + 1. b consists of all zeroes, so consists of all ones. Finally we have

-num = (a1b)¯ + 1 = a¯0b¯ + 1 = a¯0(0…0)¯ + 1 = a¯0(1…1) + 1 = a¯1(0…0) = a¯1b.

Now, we can easily isolate the last digit, using bitwise operator AND (in C++, Java it is &) with num and -num:

           a1b
&      a¯1b
——————–
= (0…0)1(0…0)

 

继续阅读

C语言速成手册(二):布尔值、条件判断、循环

Via http://www.matrix67.com/blog/archives/218 by Matrix67

目录:
C语言速成手册(一):基本数据类型、标准输出、函数
C语言速成手册(二):布尔值、条件判断、循环
C语言速成手册(三):数组、字符串、结构
C语言速成手册(四):指针、动态内存分配、标准输入
C语言速成手册(五):其它运算符、文件操作、其它函数
C语言速成手册(六):其它问题、后记

继续阅读

OI青花瓷

via 百度noip吧

哥尼斯堡七桥边我们的连线
丽洁神犇嫩模间难存的情缘
当图灵机看见这也会被停机
NP解释不了的难题
搜索会爆无向图慢慢去遍历
只为能够找到你心底的记忆
神器SPFA
队列进出我们的足迹
线性规划难找我们的交集
算心底的梦忆靠容斥原理
二进制连篇幅代我说真爱你
Dev-C感动得去编译
平衡树轻旋转你我在隔壁
将你我连一起矩阵快速幂
看你我完美结合算法多美丽
你眼带笑意
数字三角行阵间递推难了解
斐波那契数列中恩怨何时结
二叉树上的禁果摘下归你我
藏进最长非降序列里
01背包装不下曾经的点滴
一切伤痕作浮云压进栈之底
红娘一般的匈牙利
联系我们不用并查集
心如凸包体积计算不容易
增广路来拓宽一定走进你
用剪枝剪去一切别人的记忆
得与失并不用去博弈
大脑里我找你匹配KMP
仿佛昨日重现AC自动机
二分图你我牵手一起的奇迹
感动着天地

发自 WordPress for Android

C语言速成手册(一):基本数据类型、标准输出、函数

Via http://www.matrix67.com/blog/article.php?id=262 by Matrix67

目录:
C语言速成手册(一):基本数据类型、标准输出、函数
C语言速成手册(二):布尔值、条件判断、循环
C语言速成手册(三):数组、字符串、结构
C语言速成手册(四):指针、动态内存分配、标准输入
C语言速成手册(五):其它运算符、文件操作、其它函数
C语言速成手册(六):其它问题、后记

语句和语句块
    和Pascal一样,C语言的每条语句以分号结尾。
    和Pascal一样,单词和语句间的空格、回车符对编译没有影响。
    C语言的语句块用花括号标识,也就是说字符 { 相当于Pascal的begin,字符 } 相当于Pascal的end; 。语句块中最后一条语句末尾的分号不能省略。

    如果语句块里只有一条语句,语句块的标识可以省略。这就好像Pascal代码:


    里面的begin和end可以省略一样。

注释的写法
    两种情形被认为是注释。符号// 的后面(只限一行),以及符号 /* 和 */ 之间(可以跨行)。例如:
 

常用数据类型
C                  |  Pascal
——————-+————
short              |  shortint
int                |  integer
long               |  longint
long long          |  int64
unsigned short     |  byte
unsigned int       |  word
unsigned long      |  dword
unsigned long long |  qword
float              |  real
double             |  double
char               |  char

定义变量
    定义变量使用这样的格式:
类型名 变量名1, 变量名2, … , 变量名n;
    变量名的命名规则与Pascal相同:只能用大小写字母、数字或下划线,第一个字符不用数字。所不同的是,C语言中定义的名称要区分大小写。
    例如,下面的两条语句定义了三个整型变量和一个字符变量。
int a,b,c;
char ch;
    和
Pascal不同,变量的声明不一定要在整个代码前。你可以在程序中任意一个地方定义一个新的变量。定义的变量只能在当前函数(中的当前语句块)后面的代
码中使用。也就是说,不同函数之间的变量不能混用,在某循环里定义的变量在循环外面是无效的。定义在函数外的变量将作为全局变量供后面的函数使用。

定义常量
    为了告诉编译器某个变量不会改变,你可以在变量定义前加一个const。例如,下面的语句定义了一个常数:
const int maxn=2000;

基本数学运算
  作用   |  C  | Pascal
———+—–+———–
   加    | +   |  +
   减    | –   |  –
   乘    | *   |  *
   除    | /   |  / 或 div
  取余   | %   |  mod
    除法的结果是整数还是小数取决于参与运算的数是整数还是小数。10 / 4等于2,但写成 10.0 / 4 或 10 / 4.0 就得2.5了。

关于字符类型
    C语言中的字符用一对单引号' '标注。例如,'A'表示字符A。
    无法打印或可能产生冲突的字符用反斜杠加一个字符来表示,这叫做转义符。常用转义符如下:
\n  换行
\t  Tab
\a  响铃
\"  双引号
\'  单引号
\?  问号
\\  反斜杠
    因此,'\''表示一个单引号,虽然它看上去像是两个字符。

    字符类型可以依照ASCII码进行数学运算。例如,字符变量ch可能被赋值为'A'+2(这样ch就等于'C'),而'0'+'1'则等于'a'。

C语言中的赋值
    和Pascal不一样,C语言的赋值只用一个等号,等号前没有冒号。
    声明变量时后面可以跟一个等号赋初始值。
    下面的语句都是合法的:

类型转换与“名词动用”
    C语言中,不同类型的变量可以相互赋值,程序将自动转换类型(即使是数字与字符之间)。
    C语言中也存在“使动”用法(类似于Pascal中使用int64(a)扩展变量长度的用法)。假如a是整型,(double)a表示“实数版的a”;假如ch是一个字符,(int)ch就相当于Pascal中的ord(ch)。
    考虑下面的代码:

    这段代码中,a最终被赋值为122,b得到的值是20,而c的值则为字符'0';d获得的值为6.0,而e的值是6.1 。

标准输出
    输出使用printf函数。printf函数的使用方法如下:
printf (字符串, 待输出表达式1, 待输出表达式2, … , 待输出表达式n );
    C
语言的字符串用一对双引号"  "注明,里面允许有转义符。printf将把字符串输出到屏幕上。字符串中可以有若干个标识,这些标识帮后面待输出的内容
“占一个位置”。常用的标识格式为%[x][.y](c|d|f|e),其中x表示输出占的宽度,y表示保留位数;c,d,e,f四个字母表示输出类型,
你需要选择一个。c表示输出字符,d(也可以用 i
)表示输出整数,f表示输出小数,e用科学计数法表示小数。printf后面的参数依次“填入”这些标识。注意d和e,f不能混用,也就是说,你不能把一
个小数输出成整数格式,或把整数输出成小数格式(除非事先转了类型)。
    特别地,%%表示输出一个百分号。

    观察下列代码片段

    程序输出的结果为:
Welcome to Matrix67.com
4 + 5 = 9
and 4 – 5 = -1

2 * a = 00204
2 * a = 204.000000
2 * a =      204
2 * a =    00204
a = 'f'

a / b = 14.571429
a / b = 1.457143e+001
a / b = 14.571428571
a / b = 14.571
a / b =   14.571
b / a = 6.863%

c = A
c =   A
c = 65
Matrix67.com

函数的定义、返回和调用
    定义一个函数的格式如下:
函数返回类型 函数名( 参数类型1 参数名1, 参数类型2 参数名2, … , 参数类型n 参数名n )
{
    函数内容
}
    如果某个函数不返回任何数据(相当于Pascal中的“过程”),函数返回类型要写成void。如果不写返回类型,函数默认返回类型为int。
    如果某个函数不带任何参数,参数表一般留空(也可以用一个void代替)。
    为了强调某个参数在整个函数中始终不变,类型前可以标明const。

    函数的返回使用下面的语句:
return 表达式;
    执行这条语句将立即终止该函数的运行。

    下面定义的一个函数可以返回三个数的平均值:

    C语言也支持函数的内联,方法是在函数返回类型前加inline。例如:

    函数的调用方法和Pascal一样。如果调用函数所带的参数类型和定义的不一样,程序会自动转换类型。下面的语句合法地调用了刚才定义的函数:
num = average( 2, 6.5, 4.23 );
    有一点不同的是,当所调用的函数不带参数时仍然要写括号,例如:

    C
语言同样支持递归调用。由于C语言也只能调用前面定义过的函数,因此C同样需要类似于向前引用的方法。具体方法是把需要提前引用的函数的第一行复制一份提
到前面去。下面的两种做法都是正确的,其中第一种方法允许在output函数里调用后面的average,第二种则允许在这句话后面的所有函数中调用它。

    事实上,向前引用时参数名已经没有意义,因此参数名可以省略,直接写成这样:
double average (double , double , double );

    C语言中也允许在函数中定义子函数(函数的嵌套)。标准的C语言不支持在函数中定义子函数(函数的嵌套),虽然某些编译器可能支持。

一个完整的程序代码的构成
    代码前几行用于包含头文件,每行包含一个,格式如下:
#include <头文件名>
    常
用的头文件有stdlib.h, stdio.h, string.h,
math.h等等,分别提供一些常用函数、输入输出函数、字符串函数和数学相关函数。注意我们之前用的printf函数是属于stdio.h里的,因此要
使用该函数必须在代码最开头加入#include <stdio.h>。
    接下来是若干个函数。这些函数里必须有一个名为main的函数,它返回的值是一个int类型,代表程序的退出代码(0=正常退出)。程序会自动寻找这个函数作为主函数执行。

    下面的代码是一个完整的C程序代码,这是我们的第一个完整的程序代码: