zoukankan      html  css  js  c++  java
  • Linux运维之shell脚本

    一、bash漏洞

    1)bash漏洞

    bash漏洞是控制Linux计算机命令提示符的软件中存在的漏洞。
    bash是一个为GNU计划编写的Unix shell。它的名字是一系列缩写:Bourne-Again SHell ,Bourne shell是一个早期的重要shell,
    由史蒂夫·伯恩在1978年前后编写,并同Version 7 Unix一起发布。
    网络安全专家警告称,开源软件Linux中一个频繁使用的片段"Bash",发现存在安全漏洞,
    其对计算机用户造成的威胁可能要超过2014年4月爆出的"心脏出血"(Heartbleed)漏洞

    2)漏洞原理

    Bash是用于控制Linux计算机命令提示符的软件。网络安全专家表示,黑客可以利用Bash中的一个安全漏洞,对目标计算机系统进行完全控制。
    网络安全公司Trail of Bits的首席执行官丹·吉多(Dan Guido)指出:"与Heartbleed"相比,后者只允许黑客窥探计算机,
    但不会让黑客获得计算机的控制权。"他说:"利用Bash漏洞的方法也简单得多,你可以直接剪切和粘贴一行软件代码,就能取得很好的效果。"
    吉多还表示,他正考虑将自己公司非必要的服务器断网,以保护他们不会受到Bash漏洞的攻击,直到他能够修补这一漏洞为止。
    网络安全公司Rapid7的工程经理托德·比尔兹利(Tod Beardsley)则警告称,Bash漏洞的严重程度被评为10级,意味着它具有最大的影响力,
    而其利用的难度被评为"低"级,意味着黑客比较容易地利用其发动网络攻击。
    比尔兹利称:"利用这个漏洞,攻击者可能会接管计算机的整个操作系统,得以访问机密信息,并对系统进行更改等等。
    任何人的计算机系统,如果使用了Bash软件,都需要立即打上补丁。"
    

    3)修复方式

    A - centos系统
    yum clean allyum makecacheyum -y update bash
    如果是centos系统只要运行上面简单的脚本就可以。
    
    B - Ubuntu系统
    apt-get updateapt-get -y install --only-upgrade bash
    
    C - debian系统
    如果是7.5 64位 && 32位环境运行
    apt-get updateapt-get -y install --only-upgrade bash
    

    4)漏洞测试

    BASH爆出来一个远程代码执行的bash漏洞CVE-2014-6271。
    BASH除了可以将shell变量导出为环境变量,还可以将shell函数导出为环境变量!当前版本的bash通过以函数名作为环境变量名,
    以"(){"开头的字串作为环境变量的值来将函数定义导出为环境变量。
    此次爆出的bash 漏洞在于BASH处理这样的"函数环境变量"的时候,并没有以函数结尾"}"为结束,而是一直执行其后的shell命令!例如
    env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
    如果返回
    vulnerable
    this is a test
    这样的结果的话,请尽快升级
    

    二、用户登录的提示语

    Last login: Wed Feb 28 12:10:06 2018 from 192.168.1.100
    welcome to linux
    this is test
    [root@tomcat ~]# 
    
    [root@tomcat ~]# cat /etc/motd 
    welcome to linux
    [root@tomcat ~]# cat /etc/profile.d/test.sh 
    echo "this is test"
    

    三、常用变量的使用

    1)常用变量的意思

    shell特殊变量*****
    1:位置变量
    $0	获取当前执行的shell脚本的文件名,包括路径
    $n	获取当前执行的shell脚本的第n个参数值,n=1..9,当n为0时表示脚本的文件名,如果n大于9,用大括号括起来${10}
    $*	获取当前shell脚本的所有参数,将所有的命令行参数视为单个字符串,相当于"$1$2$3"...注意与$#的区别
    $#	获取当前shell命令行中参数的总个数
    $@	这个程序的所有参数"$1" "$2" "$3" "...",这是将参数传递给其他程序的最佳方式,因为他会保留所有内嵌在每个参数里的任何空白
    提示:$* 和$@的区别?
    $*	将所有的命令行所有参数视为单个字符串,等同于"$1$2$3","$*"
    $@	将命令行每个参数视为单独的字符串,等同于"$1","$2","$3"。这个将参数传递给其他程序的最佳方式,因为他会保留所有内嵌在每个参数里的任何空白
    

      

    if [ -f  file ]      如果文件存在
    if [ -d ...   ]     如果目录存在
    if [ !-n ... ]    如果是空
    if [ !-n ... ] || [ !-n ... ] 都要满足,只要其中一个为空,就要怎么的
    if [ -s file  ]    如果文件存在且非空 
    if [ -r file  ]    如果文件存在且可读
    if [ -w file  ]    如果文件存在且可写
    if [ -x file  ]    如果文件存在且可执行   
    if [ int1 -eq int2 ]    如果int1等于int2   
    if [ int1 -ne int2 ]    如果不等于    
    if [ $# -ne 2 ]    如果不等于 2
    if [ int1 -ge int2 ]       如果>=
    if [ int1 -gt int2 ]       如果>
    if [ int1 -le int2 ]       如果<=
    if [ int1 -lt int2 ]       如果<
    

    2)常用变量的使用

    [root@oldboy66 day1]# cat q.sh 
    echo $1 $2 $3 $4 $5 $9 ${10} ${11}
    echo $#
    [root@oldboy66 day1]# sh q.sh {a..z}
    a b c d e i j k
    26
    ====》$# 接收参数的总算

     简单的逻辑判断

    [root@tomcat day2]# cat abc.sh 
    [ $# -ne 2 ] &&		#-ne是不等于
    {
    	echo "must two"
    	exit 1
    }
    echo oldgirl
    ==》如果接收的参数不等于2,就输入"must two"
    ==》否则执行后面的内容
    [root@tomcat day2]# sh abc.sh 
    must two
    [root@tomcat day2]# sh abc.sh he
    must two
    [root@tomcat day2]# sh abc.sh he ab
    oldgirl
    

     exit 1 的意义

    [root@tomcat day2]# sh abc.sh he ab
    oldgirl
    [root@tomcat day2]# echo $?
    0
    [root@tomcat day2]# sh abc.sh he
    must two
    [root@tomcat day2]# echo $?
    1
    

    四、pid的作用和$$的作用

      1)不完整版

      $$ 获取当前shell的进程号(PID)

    [root@tomcat day2]# cat pid.sh 
    echo $$>/tmp/a.pid
    sleep 300
    [root@tomcat day2]# sh pid.sh &
    [1] 57267
    [root@tomcat day2]# cat /tmp/a.pid 
    57267
    [root@tomcat day2]# ps -ef|grep pid.sh|grep -v grep
    root      57267  57235  0 15:25 pts/0    00:00:00 sh pid.sh
    [root@tomcat day2]# kill -USR2 `cat /tmp/a.pid`
    [root@tomcat day2]# ps -ef|grep pid.sh|grep -v grep
    

     2)脚本完整版,意义。不会重复启动进程。启动前,先杀死原有进程

    [root@tomcat day2]# cat pid.sh 
    #!/bin/sh
    pidpath=/tmp/a.pid
    if [ -f "$pidpath" ] 
       then
          # kill -USR2 `cat $pidpath` # 这样会输出内容
          kill -USR2 `cat $pidpath` >/dev/null 2>&1
          rm -f $pidpath
    fi
    echo $$ >$pidpath
    sleep 300
    # 如果这个文件存在
    #     就去这个文件杀死
    #     并删除文件
    

    五、批量改名

    1)单个测试

    [root@tomcat day2]# cat files.log  # 名字中删除所有的finished
    stu_102999_1_finished.jpg
    stu_102999_2_finished.jpg
    stu_102999_3_finished.jpg
    stu_102999_4_finished.jpg
    stu_102999_5_finished.jpg
    [root@tomcat day2]# cat files.log |tr "
    " " "
    stu_102999_1_finished.jpg stu_102999_2_finished.jpg stu_102999_3_finished.jpg stu_102999_4_finished.jpg stu_102999_5_finished.jpg [root@tomcat day2]# 
    [root@tomcat day2]# touch `cat files.log |tr "
    " " "`
    [root@tomcat day2]# ls
    stu_102999_1_finished.jpg  stu_102999_3_finished.jpg  stu_102999_5_finished.jpg
    stu_102999_2_finished.jpg  stu_102999_4_finished.jpg 
    [root@tomcat day2]# f=stu_102999_1_finished.jpg
    [root@tomcat day2]# echo $f
    stu_102999_1_finished.jpg
    [root@tomcat day2]# echo ${f%finish*.jpg}
    stu_102999_1_
    [root@tomcat day2]# mv $f `echo ${f%finish*.jpg}`.jpg
    [root@tomcat day2]# ls stu_102999_1_.jpg 
    stu_102999_1_.jpg
    

    2)for循环批量修改

    [root@tomcat day2]# for f in `ls *fin*` ;do mv $f `echo ${f%finish*.jpg}`.jpg; done
    [root@tomcat day2]# ls
    stu_102999_1_.jpg  stu_102999_3_.jpg  stu_102999_5_.jpg
    stu_102999_2_.jpg  stu_102999_4_.jpg
    

    3)批量改后缀名

    [root@tomcat day2]# f=stu_102999_1_.jpg 
    [root@tomcat day2]# echo ${f/%jpg/htm}
    stu_102999_1_.htm
    [root@tomcat day2]# mv $f ${f/%jpg/htm}
    [root@tomcat day2]# ls stu_102999_1_.htm 
    stu_102999_1_.htm
    [root@tomcat day2]# for f in `ls *jpg`;do mv $f ${f/%jpg/htm};done
    [root@tomcat day2]# ls *.htm
    stu_102999_1_.htm  stu_102999_2_.htm  stu_102999_3_.htm  stu_102999_4_.htm  stu_102999_5_.htm
    

    六、变量的数值计算

    1)变量计算的方式,命令

      (())  let  expr  $[] 前面整数   bc最后小数

      对计算命令的时间,耗时对比

    time for i in $(seq 11111);do count=${#chars};done;			  最快
    time for i in $(seq 11111);do count=`echo ${chars}|wc -L`;done;		  最慢
    time for i in $(seq 11111);do count=`echo expr length "${chars}"`;done	  其次  
    

    2)各个运算符的意义

    运算符				意义
    ++ --			增加及减少,可前置也可放在结尾
    + - !			一元的正号与负号;逻辑与位的取反
    * / %			乘法、除法、与取余
    + -			加法、减法
    < <= > >=		比较符号
    == !=			相等于不相等	一个"="是赋值
    <<  >>			向左位移  向右位移
    &			位的AND
    ^			位的异或
    |			位的或
    &&			逻辑的AND
    ||			逻辑的OR
    ?:			条件表达式
    = += -= *= /= &=	赋值运算符 a+=1 都相当于a=a+1
    ^=  <<=  >>= |=
    

    运算例子

    [root@oldboy66 ~]# ((a=1+2**3-4%3))			==》1+8-1
    [root@oldboy66 ~]# echo $a
    8
    [root@oldboy66 ~]# b=$((a=1+2**3-4%3))
    [root@oldboy66 ~]# echo $b
    8
    [root@oldboy66 ~]# echo $((a=1+2**3-4%3))
    8
    [root@oldboy66 ~]# echo $a
    8
    [root@oldboy66 ~]# echo $((a+=1))
    9
    [root@oldboy66 ~]# echo $a
    9
    [root@oldboy66 ~]# echo $((a++))
    9
    [root@oldboy66 ~]# echo $a
    10
    [root@oldboy66 ~]# echo $((++a))
    11
    

    小结

      对++,--。变量在前,先输出原来的值,在输出计算表达后的值;变量在后。就是先运算输出表达式后的值,后又输出计算之后的值

    3)比较大小和取余

    比较大小,不成立是0,成立是1
    [root@oldboy66 ~]# echo $((3>2))
    1
    [root@oldboy66 ~]# echo $((3<2))
    0
    [root@oldboy66 ~]# echo $((3=2))
    -bash: 3=2: attempted assignment to non-variable (error token is "=2")
    [root@oldboy66 ~]# echo $((3==2))
    0
    [root@oldboy66 ~]# echo $((100*(100+1)/2))
    5050
    下面是取余
    [root@oldboy66 ~]# echo $((100%5))
    0
    [root@oldboy66 ~]# echo $((100%3))
    1
    

    4)简单四则运算

    案例一:固定值执行

    [root@oldboy66 day1]# cat jisuan.sh 
    #!/bin/bash
    a=6
    b=2
    echo "a-b =$(($a - $b))"
    echo "a+b =$(($a + $b))"
    echo "a*b =$(($a * $b))"
    echo "a/b =$(($a / $b))"
    echo "a**b =$(($a ** $b))"
    echo "a%b =$(($a % $b))"
    [root@oldboy66 day1]# sh jisuan.sh 
    a-b =4
    a+b =8
    a*b =12
    a/b =3
    a**b =36
    a%b =0
    

    案例二,传参方式执行

    [root@oldboy66 day1]# cat jisuan2.sh 
    #!/bin/bash
    a=$1
    b=$2
    echo "a-b =$(($a - $b))"
    echo "a+b =$(($a + $b))"
    echo "a*b =$(($a * $b))"
    echo "a/b =$(($a / $b))"
    echo "a**b =$(($a ** $b))"
    echo "a%b =$(($a % $b))"
    [root@oldboy66 day1]# sh jisuan2.sh 6 4
    a-b =2
    a+b =10
    a*b =24
    a/b =1
    a**b =1296
    a%b =2
    

    案例三、实现一个简单的四则计算器,通过命令行参数的方式实现脚本的功能

    [root@oldboy66 day1]# cat jisuan3.sh
    echo $(($1$2$3))
    [root@oldboy66 day1]# sh jisuan3.sh 3+4		由于挨在一起,相当于只接收了一个参数,只传给了$1
    7
    或
    [root@oldboy66 day1]# cat jisuan4.sh 
    echo $(($1))
    [root@oldboy66 day1]# sh jisuan4.sh 7+3
    10
    

    5)let 命令的用法

    格式:let赋值表达式
    注:let赋值表达式功能等同于:((赋值表达式))
    给自变量i+8,例如
    [root@oldboy66 ~]# i=2
    [root@oldboy66 ~]# let i=i+8
    [root@oldboy66 ~]# echo $i
    10
    [root@oldboy66 ~]# i=2
    [root@oldboy66 ~]# i=i+8	<==去掉let定义
    [root@oldboy66 ~]# echo $i
    i+8
    

    七、expr命令的用法

    1)expr 命令的计算

    expr命令一般用于整数值,但也可用于字符串,用来求表达式变量的值同时expr是一个手工命令行计算器
    语法:expr Expression
    [root@oldboy66 ~]# expr 2 + 2
    4
    [root@oldboy66 ~]# expr 2+2
    2+2
    [root@oldboy66 ~]# expr 2 *  2		乘法 *需要转义
    4
    [root@oldboy66 ~]# expr 2 /  2
    1
    [root@oldboy66 ~]# expr 5 % 2
    1
    

       注意:

            1:运算符及计算的数字左右都有至少一个空格
            2:使用乘号时,必须用反斜线屏蔽器特定含义。因为shell可能会误解星号的含义
       增量计数:
           expr在循环中可用于增量计算。首先,循环初始化为0,然后循环值加1,反引号的用法为命令替代。最基本的一种是从(expr)命令接受输出并将值放入循环变量

    [root@oldboy66 ~]# i=0
    [root@oldboy66 ~]# i=`expr $i + 1`
    [root@oldboy66 ~]# echo $i
    1
    [root@oldboy66 ~]# b=`expr $i + 1`
    [root@oldboy66 ~]# echo $b
    2
    [root@oldboy66 ~]# expr $[2+3]
    5
    [root@oldboy66 ~]# expr $[ 2 + 3 ]
    5
    [root@oldboy66 ~]# echo $[2+3]
    5
    

    2)expr的特殊用法

    案例一:判断是否是整数

    [root@tomcat day3]# cat expr2.sh 
    #!/bin/sh
    # 判断是否是整数
    expr 1 + $1 &>/dev/null
    if
        [ $? -eq 0 ]
        then
    	echo "整数"
        else
    	echo "非整数"
    fi
    [root@tomcat day3]# sh expr2.sh 2
    整数
    [root@tomcat day3]# sh expr2.sh 2.5
    非整数

    案例二:判断文件后缀名

    [root@oldboy66 day1]# cat expr.sh 
    #!/bin/sh
    # 判断后缀名
    if
        expr "$1" : ".*.pub" &>/dev/null
        then
    	echo "you are using $1"
        else
    	echo "pls use *.pub file"
    fi
    [root@oldboy66 day1]# sh expr.sh n.sh 
    pls use *.pub file
    [root@oldboy66 day1]# sh expr.sh oldboy.pub 
    you are using oldboy.pub
    

    案例三:read和expr结合判断整数和浮点数

    [root@tomcat day3]# cat expr3.sh 
    #!/bin/sh
    while true
    do
        read -p "Pls input:" a
        expr $a + 0 >/dev/null 2>&1
        [ $? -eq 0 ] && echo int||echo chars
    done
    [root@tomcat day3]# sh expr3.sh 
    Pls input:3
    int
    Pls input:3.5
    chars
    Pls input:quit
    chars
    Pls input:^C
    [root@tomcat day3]# 
    

    八、read 用法

    1)read基本用法

    -p prompt	设置提示信息
    -t timeout 	设置输入等待的时间,单位默认为秒
    [root@oldboy66 day1]# read -t 5 -p "pls input:" a		如果5秒钟不输出内容,则退出。pls input,是输出的提示符,a是变量,输出的内容赋值给a
    pls input:1
    [root@oldboy66 day1]# echo $a
    1
    [root@oldboy66 day1]# read -t 5 -p "pls input:" a b
    pls input:1 3
    [root@oldboy66 day1]# echo $a
    1
    [root@oldboy66 day1]# echo $b
    3
    

    2)read 实现4则运算脚本

    [root@tomcat day3]# cat read2.sh 
    #!/bin/sh
    read -t 10 -p "pls input:" a b
    echo "a-b=$(( $a - $b ))"
    echo "a+b=$(( $a + $b ))"
    echo "a*b=$(( $a * $b ))"
    echo "a/b=$(( $a / $b ))"
    echo "a**b=$(( $a ** $b ))"
    echo "a%b=$(( $a % $b ))"
    [root@tomcat day3]# sh read2.sh 
    pls input:24 4
    a-b=20
    a+b=28
    a*b=96
    a/b=6
    a**b=331776
    a%b=0
    

    3)read 实现4则运算脚本,改良版

    [root@tomcat day3]# cat read.sh 
    #!/bin/sh
    echo "This is a calulation script,welcome to use"
    read  -p "pls input:" a b
    expr $a + $b >/dev/null
    if [ $? -eq 0 ]
        then
            echo "a-b=$(( $a - $b ))"
            echo "a+b=$(( $a + $b ))"
            echo "a*b=$(( $a * $b ))"
            echo "a/b=$(( $a / $b ))"
            echo "a**b=$(( $a ** $b ))"
            echo "a%b=$(( $a % $b ))"
        else
            echo "You can only enter two value and they are integer."
            echo "please int two"
            exit 1
    fi
    [root@tomcat day3]# sh read.sh
    This is a calulation script,welcome to use
    pls input:5 3
    a-b=2
    a+b=8
    a*b=15
    a/b=1
    a**b=125
    a%b=2
    View Code

    4)实现2个整数比较大小,read以交互式的方式实现

    #!/bin/sh
    # [ -z STRING ] “STRING” 的长度为零则为真。
    read -p "Pls input two num:" a b
    # 首先确定输入的是2个数
    # 如果 a 或者 b 任意一个长度为0 ,都执行请再次输入,并退出
    [ -z "$a" ] || [ -z "$b" ] && {
        echo "Pla input two num again"
        exit 1
    }
    # 在确定是不是输入的2个整数
    expr $a + 0 &>/dev/null
    RETVAL1=$?
    expr $b + 0 &>/dev/null
    RETVAL2=$?
    test $RETVAL1 -eq 0 -a $RETVAL2 -eq 0 ||{
        echo "Pla input two intnum again"
        exit 2
    }
    [ $a -lt $b ] && {
        echo "$a < $b"
        exit 0
    }
    [ $a -eq $b ] && {
        echo "$a = $b"
        exit 0
    }
    [ $a -gt $b ] && {
        echo "$a > $b"
        exit 0
    }
    View Code

    5)命令行直接输入比较大小

    #!/bin/sh
    a=$1
    b=$2
    [ $# -ne 2 ] && {
        echo "USAGE:$0 NUM1 NUM2"
        exit 1
    }
    
    expr $a + 0 &>/dev/null
    RETVAL1=$?
    expr $b + 0 &>/dev/null
    RETVAL2=$?
    
    test $RETVAL1 -eq 0 -a $RETVAL2 -eq 0 ||{
        echo "Pla input two intnum again"
        exit 2
    }
    [ $a -lt $b ] && {
        echo "$a < $b"
        exit 0
    }
    [ $a -eq $b ] && {
        echo "$a = $b"
        exit 0
    }
    [ $a -gt $b ] && {
        echo "$a > $b"
        exit 0
    }
    View Code

    6)read 实现简单的菜单功能

    [root@tomcat day3]# cat menu.py 
    menu(){
    cat <<END
    	1.[install lamp]
    	2.[install lnmp]
    	3.[exit]
    	pls input the num you want;
    END
    	read -t 15 a
    }
    menu
    
    [ $a -eq 1 ]&&{
       echo "installing lamp"
       sleep 3
       echo "lamp is installed"
       exit
    }
    
    [ $a -eq 2 ]&&{
       echo "installing lnmp"
       sleep 3
       echo "lnmp is installed"
       exit
    }
    [ $a -eq 3 ]&&{
       exit
    }
    
    [ ! $a -eq 1 -o ! $a -eq 2 -o ! $a -eq 3 ] &&{
        echo "Please enter your correct choice"
        exit 1
    } 

    九、bc的用法

    1)直接输入bc,进入bc计算器

    [root@oldboy66 day1]# bc
    bc 1.06.95
    Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
    This is free software with ABSOLUTELY NO WARRANTY.
    For details type `warranty'. 
    100*3
    300
    quit
    

    2)输出值给bc进行运算

    [root@oldboy66 day1]# echo 1+2|bc
    3
    [root@oldboy66 day1]# echo 1+2.4|bc
    3.4
    [root@oldboy66 day1]# echo 5.23*3.13|bc
    16.36
    [root@oldboy66 day1]# echo "scale=6;5.23*3.13"|bc	scale是保留小数点几位
    16.3699
    [root@oldboy66 day1]# echo 5.23*3.13|bc -l
    16.3699
    [root@oldboy66 day1]# echo "scale=5;5.23/3.13"|bc
    1.67092
    [root@oldboy66 day1]# echo 5.23/3.13|bc -l
    1.67092651757188498402
    [root@oldboy66 day1]# echo "obase=2;255"|bc		后面的10进制转换成前面的2进制
    11111111
    

    3)算式拼接:输出内容如1+2+3+4+5+6+7+8+9+10=55

    [root@oldboy66 day1]# echo `seq -s '+' 10`=`seq -s "+" 10|bc`
    1+2+3+4+5+6+7+8+9+10=55
    [root@tomcat day3]# echo "`seq -s '+' 10`="$((`seq -s "+" 10`))
    1+2+3+4+5+6+7+8+9+10=55
    [root@tomcat day3]# echo `seq -s '+' 10`=`seq -s " + " 10|xargs expr`
    1+2+3+4+5+6+7+8+9+10=55
    [root@tomcat day3]# echo `seq -s " + " 10`|xargs expr
    55
    
    [root@oldboy66 day1]# seq -s " + " 10
    1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10
    [root@oldboy66 day1]# echo {1..10}|tr " " "+"
    1+2+3+4+5+6+7+8+9+10
    [root@oldboy66 day1]# echo {1..10}|tr " " "+"|bc
    55
    

    九、typeset命令的用法:使用整数变量之间进行计算

    [root@tomcat day3]# typeset -i a=1 b=3
    [root@tomcat day3]# a=a+b
    [root@tomcat day3]# echo $a
    4
    [root@tomcat day3]# typeset -i a=2 b=4
    [root@tomcat day3]# c=a+b
    [root@tomcat day3]# echo $c
    a+b
    [root@tomcat day3]# b=a+b
    [root@tomcat day3]# echo $b
    6

     

      

      

  • 相关阅读:
    linux的常用命令
    linux系统环境与文件权限
    MySQL常用数据类型
    【bzoj4641】基因改造 特殊匹配条件的KMP
    【bzoj4550】小奇的博弈 博弈论+dp
    【bzoj3991】[SDOI2015]寻宝游戏 树链的并+STL-set
    【bzoj1304】[CQOI2009]叶子的染色 树形dp
    【bzoj4715】囚人的旋律 dp
    【bzoj4008】[HNOI2015]亚瑟王 概率dp
    【bzoj4444】[Scoi2015]国旗计划 倍增
  • 原文地址:https://www.cnblogs.com/linu/p/8496209.html
Copyright © 2011-2022 走看看