C基础 mariadb处理简单案例
引言
MariaDB 是一款灰常不错开源数据库. 这里直接用它来解决业务问题.
业务需求:
现在数据库中表示按照天分表的. 突然我们需要按照月来处理数据.
例如输入一个玩家id, 查找这个玩家这个月内看了一件事几次. 我们先搭建一个环境.
操作系统:
Linux version 4.4.--generic (buildd@lgw01-)
(gcc version 5.3. (Ubuntu 5.3.-14ubuntu2) )
#-Ubuntu SMP Thu May :: UTC
首先安装 MariaDB数据库
sudo apt-get install mariadb-server
sudo apt-get install mariadb-client
sudo apt-get install libmariadb2
sudo apt-get install libmariadb-client-lgpl-dev
sudo apt-get install libreoffice-mysql-connector
后面是C访问 MariaDB驱动. 这里扯一点, 目前关于MariaDB不懂问题, 搜不见直接当成mysql开始搜.
MariaDB安装成功后默认是开启的, 看下面图描述

后面搭建测试环境 首先 看 oss_musicelves.sql
-- MySQL dump 10.10
--
-- Host: localhost Database: oss_log
-- ------------------------------------------------------
-- Server version 5.5.24-tmysql-1.4 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; --
-- Table structure for table `oss_musicelves`
-- DROP TABLE IF EXISTS `oss_musicelves`;
CREATE TABLE `oss_musicelves` (
`record_id` bigint(20) NOT NULL AUTO_INCREMENT,
`account_id` bigint(20) NOT NULL,
`server_id` int(11) NOT NULL,
`char_id` bigint(20) NOT NULL,
`char_sex` int(11) NOT NULL,
`type_id` int(11) NOT NULL,
`timeStamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`ptype` int(11) NOT NULL,
`specifytype` int(11) NOT NULL,
`childtype` int(11) NOT NULL,
PRIMARY KEY (`record_id`),
KEY `idx_specifytype` (`specifytype`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=latin1; --
-- Dumping data for table `oss_musicelves`
-- /*!40000 ALTER TABLE `oss_musicelves` DISABLE KEYS */;
LOCK TABLES `oss_musicelves` WRITE;
INSERT INTO `oss_musicelves` VALUES (1,411948833,84869352,27899597414400801,0,1812,'2016-05-31 14:27:41',0,1,1),(2,1344702709,90964200,30422720614402293,0,1812,'2016-05-31 14:58:26',0,1,1),(3,706409913,90964200,30422720614401465,1,1812,'2016-05-31 14:58:27',0,1,2),(4,706409913,392964857,30422720614401465,1,1812,'2016-05-31 14:58:59',0,2,4),(5,1344702709,392964857,30422720614402293,0,1812,'2016-05-31 14:58:59',0,2,4),(6,706409913,90964200,30422720614401465,1,1812,'2016-05-31 15:04:52',0,1,2),(7,706409913,392964857,30422720614401465,1,1812,'2016-05-31 15:05:54',0,2,4),(8,1344702709,392964857,30422720614402293,0,1812,'2016-05-31 15:05:54',0,2,4),(9,1344702709,90964200,30422720614402293,0,1812,'2016-05-31 15:10:29',0,1,1),(10,706409913,90964200,30422720614401465,1,1812,'2016-05-31 15:10:32',0,1,2),(11,1344702709,392964857,30422720614402293,0,1812,'2016-05-31 15:10:54',0,2,4),(12,3145910262,90964200,29520779366416374,1,1812,'2016-05-31 15:30:00',0,1,1),(13,1372825842,90964200,30173879500803314,1,1812,'2016-05-31 15:30:01',0,1,2),(14,3145910262,392964857,29520779366416374,1,1812,'2016-05-31 15:30:04',0,2,4),(15,1372825842,392964857,30173879500803314,1,1812,'2016-05-31 15:30:04',0,2,4),(16,3145910262,392964857,29520779366416374,1,1812,'2016-05-31 15:34:24',0,2,4),(17,1372825842,392964857,30173879500803314,1,1812,'2016-05-31 15:34:24',0,2,4),(18,706409913,90964200,30422720614401465,1,1812,'2016-05-31 15:40:14',0,1,1),(19,1344702709,90964200,30422720614402293,0,1812,'2016-05-31 15:40:16',0,1,2),(20,3145910262,392964857,29520779366416374,1,1812,'2016-05-31 15:42:19',0,2,4),(21,1372825842,392964857,30173879500803314,1,1812,'2016-05-31 15:42:19',0,2,4),(22,1027763684,90964200,30175730790400484,0,1812,'2016-05-31 16:56:33',1,1,1),(23,1372825842,90964200,30173879500803314,1,1812,'2016-05-31 16:56:50',0,1,2),(24,1372825842,392964857,30173879500803314,1,1812,'2016-05-31 16:57:37',0,2,3),(25,1027763684,392964857,30175730790400484,0,1812,'2016-05-31 16:57:37',1,2,3),(26,1372825842,392964857,30173879500803314,1,1812,'2016-05-31 17:04:33',0,2,3),(27,1027763684,392964857,30175730790400484,0,1812,'2016-05-31 17:04:33',1,2,3),(28,1027763684,90964200,30175730790400484,0,1812,'2016-05-31 17:14:15',1,1,2),(29,1372825842,392964857,30173879500803314,1,1812,'2016-05-31 17:14:50',0,2,3),(30,1027763684,392964857,30175730790400484,0,1812,'2016-05-31 17:14:50',1,2,3),(31,751699770,90964200,30175199027201850,1,1812,'2016-05-31 18:14:59',1,1,1);
UNLOCK TABLES;
/*!40000 ALTER TABLE `oss_musicelves` ENABLE KEYS */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
这个 oss_musicelves.sql 文件主要功能是创建 oss_musicelves数据库, 并填充数据.
还有一个 搭建环境 的 脚本 mariadb_test.sql 和上一个sql文件放在同一个目录下.
# 创建一个测试数据库
create database oss_log; # 进入oss_log 数据库
use oss_log; # 创建 oss_musicelves 数据库, 并导入数据
source oss_musicelves.sql; # 批量创建表和数据
create table 2016_6_1_oss_musicelves select * from oss_musicelves;
create table 2016_6_2_oss_musicelves select * from oss_musicelves;
create table 2016_6_3_oss_musicelves select * from oss_musicelves;
create table 2016_6_4_oss_musicelves select * from oss_musicelves;
create table 2016_6_5_oss_musicelves select * from oss_musicelves;
create table 2016_6_9_oss_musicelves select * from oss_musicelves;
create table 2016_6_10_oss_musicelves select * from oss_musicelves;
create table 2016_6_12_oss_musicelves select * from oss_musicelves; # 查询表是否创建成功
show tables; # 这里处理 拿到的数据
select distinct table_name from information_schema.columns where table_name like '2016_6_%_oss_musicelves';
直接放在 MariaDB控制台中直接刷进去. 搭建的具体环境如下

到这里环境基本搭建好了. MariaDB入门等等, 完全可以当做mysql 学习温故一遍.
前言
上面问题就是 原本 是 select * from oss_musicelves; 就可以解决的问题.
这里 需要 输入年和月 外加一些特殊条件 . select * from %_%_%_oss_musicelves; 解决. 单纯用sql脚本也可以解决.非常复杂.用的不熟.
这里首先通过 shell 脚本处理
touch getmouths.sh
chmod +x getmouths.sh
vi getmouths.sh
具体的脚本 内容 如下
#!/bin/sh #得到输入的玩家ptid
if [ $# -lt ]
then
echo "uage: $0 [ptid]"
exit -
fi
ptid=$ mouth=$(date +%m | sed s'/^0//')
#第一个参数是月份
if [ $# -ge ]
then
mouth=$
fi #第二个参数是年
year=$(date +%Y)
if [ $# -ge ]
then
year=$
fi #得到查询的随机表名
tbname="\"${year}_${mouth}_%_oss_musicelves\"" #这里得到mysql 中所有合法表名
rm -rf __tmp
touch __tmp #开始查询数据库了, 需要以root权限启动这个脚本
mysql -e "select distinct table_name from information_schema.columns where table_name like $tbname" | awk 'NR>1' | while read name
do
mysql -e "select count(*) from oss_log.$name where specifytype = 1 and char_id = $ptid" | awk 'NR>1' | while read cut
do
echo "$name : $cut"
echo $cut >> __tmp
break
done
done #统计表里面的数据
sum=$(cat __tmp | awk '{s+=$1} END {print s}')
rm -rf __tmp # 最后输出统计结果
echo "$year-$mouth sum: $sum"
使用脚本 截图

通过shell可以完成 我们的需求. Linux上shell真好用. window的bat不好用.
正文
第一部分 : 让C调用MariaDB跑通
先看 测试Demo mariadb_demo.c
#include <stdio.h>
#include <stdlib.h>
#include <mysql.h> /*
* 第一个 mariadb程序
*/
int main(int argc, char *argv[]) {
// 创建数据连接对象
MYSQL *con = mysql_init(NULL);
if (con == NULL) {
fprintf(stderr, "%s\n", mysql_error(con));
exit(EXIT_FAILURE);
} if (!mysql_real_connect(con, "localhost", "root", "", NULL, , NULL, )) {
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(EXIT_FAILURE);
} if (mysql_query(con, "show databases;")) {
fprintf(stderr, "%s\n", mysql_error(con));
mysql_close(con);
exit(EXIT_FAILURE);
} puts("mariadb is connect and run succesed!");
mysql_close(con); return ;
}
具体的编译 命令
su root
gcc -Wall -ggdb2 -I/usr/include/mariadb -o mariadb_demo.out mariadb_demo.c -lmysqlclient
./mariadb_demo.out
运行结果 如下

到这里基本C 调用 MariaDB 基本流程跑通了. 但是很不爽. 只能通过root用户使用.
那我们改变这里不爽. 进入第二部分. 扩展资料 c in mariadb http://stackoverflow.com/questions/17265471/using-mariadb-in-c
第二部分 : 通过普通用户完成业务需求.
先创建普通用户 csz, 密码是 1413222, 并并且给其 select 读权限.
su root
mysql drop user csz;
create user 'csz'@'%' identified by '';
grant select on *.* to 'csz'@'%';
# 立即刷新
flush privileges;
后面登录试试
mysql -ucsz -p1314222 -h127.0.0.1

主要是mariadb默认关闭远程访问. 后面我们开启安全访问模式试试
su root
/etc/init.d/mysql stop
mysqld_safe --skip-grant-tables

后面再开启一个会话 . 重新输入 mysql -ucsz -p1314222 -h127.0.0.1 , 解决可以了

到这里 通过新建的 csz 用户访问成功. 好了. 那我们开始写一个 msyql c 代码处理我们的业务. 按照月来访问. 那我们开始写代码.代码的总的思路是拼接一个这样的串
#目标拼接 串内容
select sum(c) from (
select count(*) as c from 2016_6_1_oss_musicelves where specifytype=1 and char_id = 30422720614402293
union all
select count(*) from 2016_6_2_oss_musicelves where specifytype=1 and char_id = 30422720614402293
union all
select count(*) from 2016_6_3_oss_musicelves where specifytype=1 and char_id = 30422720614402293
union all
select count(*) from 2016_6_4_oss_musicelves where specifytype=1 and char_id = 30422720614402293
union all
select count(*) from 2016_6_5_oss_musicelves where specifytype=1 and char_id = 30422720614402293
union all
select count(*) from 2016_6_9_oss_musicelves where specifytype=1 and char_id = 30422720614402293
union all
select count(*) from 2016_6_10_oss_musicelves where specifytype=1 and char_id = 30422720614402293
union all
select count(*) from 2016_6_12_oss_musicelves where specifytype=1 and char_id = 30422720614402293
) as t;
具体看 getmouths.c 文件 内容
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <mysql.h> #define _INT_BUF (4098)
// 得到查询数据表内容
#define _STR_SQLTABLES \
"select distinct table_name from information_schema.columns where table_name like '%d_%d_%%_oss_musicelves'"
#define _STR_SQLSELECT \
"select count(*) as c from %s where specifytype=1 and char_id = %lld" // 基础的mariadb 错误关闭函数
static inline void _err_mariadb(MYSQL *con) {
fprintf(stderr, "_err_mariadb error: %s\n", mysql_error(con));
mysql_close(con);
exit(EXIT_FAILURE);
} /*
* 处理 oss_musicelves 一个月的所有表.
*/
int main(int argc, char* argv[]) {
long long ptid;
time_t rt = time(NULL);
struct tm *pt = localtime(&rt);
int year = pt->tm_year + ;
int mouth = pt->tm_mon + ; // 先简单检测输入
if(argc <= ) {
fprintf(stderr, "%s [ptid] [mouth] [year]\n", argv[]);
exit(EXIT_FAILURE);
} // 先得到 ptid 数据
ptid = atoll(argv[]);
// 得到当前月份
if(argc >= )
mouth = atoi(argv[]);
// 得到当前年份
if(argc >= )
year = atoi(argv[]);
// 简单检测结果是否合法
if(ptid < || mouth <= || mouth> || year<) {
fprintf(stderr, "%s %lld %d %d is error!\n", argv[], ptid, mouth, year);
exit(EXIT_FAILURE);
} // 输出结果
printf("%s %lld %d %d start run!\n", argv[], ptid, mouth, year); // 开始用mysql 访问我们需要访问的数据结果了
MYSQL *con = mysql_init(NULL);
if(con == NULL) {
fprintf(stderr, "mysql_init error: %s\n", mysql_error(con));
exit(EXIT_FAILURE);
}
if(!mysql_real_connect(con, "127.0.0.1", "csz", "", "oss_log", , NULL, ))
_err_mariadb(con); char sqls[_INT_BUF];
int sqlen = ;
sprintf(sqls, _STR_SQLTABLES, year, mouth);
if(mysql_query(con, sqls))
_err_mariadb(con); // 开始得到结果
MYSQL_RES *ret = mysql_store_result(con);
if(NULL == ret)
_err_mariadb(con);
MYSQL_ROW row;
int i = , nr = ;
while(!!(row = mysql_fetch_row(ret))) {
if(i == ) {
sqlen = sprintf(sqls, "select sum(c) from (\n" _STR_SQLSELECT, row[], ptid);
i = ;
continue;
}
// 后面正常拼接
nr = sprintf(sqls + sqlen, "\nunion all\n" _STR_SQLSELECT, row[], ptid);
if((sqlen += nr) >= _INT_BUF) {
fprintf(stderr, "sprintf while %d too length.\n", sqlen);
goto __return_free;
}
}
if(i == ) {
printf("sum %lld %d/%d: 0\n", ptid, year, mouth);
goto __return_free;
} // 这里处理有的数据
nr = sprintf(sqls + sqlen, "\n) as t;");
if((sqlen += nr) >= _INT_BUF) {
fprintf(stderr, "sprintf end %d too length.\n", sqlen);
goto __return_free;
}
// 内存用完了就直接释放
mysql_free_result(ret);
ret = NULL; printf("sql : \n\t%s\n", sqls);
// 开始输出统计结果
if(mysql_query(con, sqls))
_err_mariadb(con);
if((ret = mysql_store_result(con))==NULL)
_err_mariadb(con);
//得到结果直接返回
if(!!(row=mysql_fetch_row(ret)))
printf("sum %lld %d/%d: %s\n", ptid, year, mouth, row[]);
else
puts("select is empty!"); __return_free:
// 释放用过的内存
mysql_free_result(ret);
// 关闭打开的 数据库访问对象
mysql_close(con);
return ;
}
编译命令
gcc -Wall -ggdb2 -I/usr/include/mariadb -o getmouths.out getmouths.c -lmysqlclient
最终运行结果是

如果想详细了解关于mariadb c驱动的api使用, 可以参照老外写的很好理解.
mysqlc demo http://zetcode.com/db/mysqlc/
到这里就结束了, 关于C 访问数据库能力也基本打通了.
后记
错误是难免, 欢迎学习进步~~~ 未来什么都不确定, 可以确定是没有未来, 只有现在还在装逼 .
后面经过实践 找到更好的解决方案 采用 mysql 存储过程
-- 最终结果令人满意, mysql存储过程
delimiter $$
drop procedure if exists oss_log.proc_oss_monopolycollect;
-- yr:年份, mh:月份, qq:查询QQ号, cut:输出当月统计的个数
create procedure oss_log.proc_oss_monopolycollect(in yr int, in mh int, in qq int, out cut int)
begin
set @ltname = concat(yr, '_', mh , '_%_oss_monopolycollect'); select replace(
group_concat(distinct(table_name)),
',',
' where specifytype = 1 and account_id = {account_id} union all select count(*) from oss_log.'
) into @sqlstr
from information_schema.columns where table_name like @ltname; -- 添加前面和尾巴部分
set @sqlstr = concat('select sum(c) into @sumc from (select count(*) as c from oss_log.',
@sqlstr,
' where specifytype = 1 and account_id = {account_id}) as t;');
-- 替换占位符, 得到最终的串内容
set @sqlstr = replace(@sqlstr, "{account_id}", qq); -- 预编译并执行
prepare stmt from @sqlstr;
-- 开始执行
execute stmt;
-- 删除预编译的结果
deallocate prepare stmt; -- 返回结果
set cut = @sumc;
end
$$
delimiter ;
测试 脚本 如下
-- 测试上面存储过程
call oss_log.proc_oss_monopolycollect(2016, 5, 9331453, @cut);
select @cut;
set @cut:=NULL;
drop procedure if exists oss_log.proc_oss_monopolycollect
这里基本就解决 遇到的问题. 最后想说一句, 真jb长!
C基础 mariadb处理简单案例的更多相关文章
- SpringBoot基础学习(一) SpringBoot概念、简单案例实现、单元测试及热部署讲解
SpringBoot概念 Spring优缺点分析 Spring优点 Spring是Java企业版(Java Enterprise Edition,JEE,也称J2EE)的轻量级代替品,无需开发重量级的 ...
- java基础之Socket编程概述以及简单案例
概述: 用来实现网络互连的 不同的计算机上 运行的程序间 可以进行数据交互 也就是用来在不同的电脑间, 进行数据传输. 三大要素: IP地址: 设备(电脑,手机,ipad)在网络中的唯一标识. 组成 ...
- SSM框架整合(Spring+SrpingMVC+Mybatis) 简单案例
简介: SSM框架是Spring,SpringMVC 和Mybatis框架的整合,是标准的MVC模式,将整个系统划分为表现层,controller层,service层,dao层四层. Spring实现 ...
- 鸿蒙内核源码分析(编译过程篇) | 简单案例窥视GCC编译全过程 | 百篇博客分析OpenHarmony源码| v57.01
百篇博客系列篇.本篇为: v57.xx 鸿蒙内核源码分析(编译过程篇) | 简单案例窥视编译全过程 | 51.c.h.o 编译构建相关篇为: v50.xx 鸿蒙内核源码分析(编译环境篇) | 编译鸿蒙 ...
- JS基础(超级简单)
1 JS基础(超级简单) 1.1 数据类型 1.1.1 基本类型: 1) Number:特别注意:NaN的检测方法:Nan!=NaN;或者使用isNaN方法 2) ...
- JMeter基础之一 一个简单的性能测试
JMeter基础之一 一个简单的性能测试 上一节中,我们了解了jmeter的一此主要元件,那么这些元件如何使用到性能测试中呢.这一节创建一个简单的测试计划来使用这些元件.该计划对应的测试需求. 1)测 ...
- Servlet请求头response应用简单案例
Servlet请求头response应用简单案例:访问AServlet重定向到BServlet,5秒后跳到CServlet,并显示图片: AServlet package cn.yzu; import ...
- winform 通过 html 与swf 交互 简单案例
在上一篇 winform 与 html 交互 简单案例 中讲了winform与html之间的简单交互,接下来的内容是在winform中以html为中转站,实现将swf嵌入winform中并实现交互. ...
- [Design Pattern] Front Controller Pattern 简单案例
Front Controller Pattern, 即前端控制器模式,用于集中化用户请求,使得所有请求都经过同一个前端控制器处理,处理内容有身份验证.权限验证.记录和追踪请求等,处理后再交由分发器把请 ...
随机推荐
- Luogu1092 NOIP2004虫食算(搜索+高斯消元)
暴力枚举每一位是否进位,然后就可以高斯消元解出方程了.然而复杂度是O(2nn3),相当不靠谱. 考虑优化.注意到某一位进位情况的变化只会影响到方程的常数项,于是可以在最开始做一次高斯消元算出每个未知数 ...
- 计蒜客 17417 Highest Tower(思维+图论)
题解: 实际上一个可行解即选取长和宽的一个,使得最后每一组选第一维的数值都不同 在此基础上,使得另一维的和最大. 然后建立图论模型 对于每一个方块,在a和b之间连边. 对于选择的方案,如果选择a-&g ...
- 【BZOJ1941】Hide and Seek(KD-Tree)
[BZOJ1941]Hide and Seek(KD-Tree) 题面 BZOJ 洛谷 题解 \(KD-Tree\)对于每个点搜一下最近点和最远点就好了 #include<iostream> ...
- Django CRM系统
本节内容 业务痛点分析 项目需求讨论 使用场景分析 表结构设计 业务痛点分析 我2013年刚加入老男孩教育的时候,学校就一间教室,2个招生老师,招了学生后,招生老师就在自己的excel表里记录一下,每 ...
- linux环境下,接着lnmp,安装redis
linux环境下,安装redis 操作记录: 回到家目录 cd ~查看 ls进入 lump cd lnmp1.3-fullls??? sudo ./addons.sh //---进入后选 ...
- ARM汇编程序闪烁灯与其反汇编代码比较
/* *LED闪烁 *led.s */ #define GPJ0CON 0xE0200240 #define GPJ0DAT 0xE0200244 .global _start //把 _start ...
- 阿里C++研发实习二面和三面面经
下午连着面了阿里爸爸的二面和三面,非常不明白别人的三面都是hr了,为什么我还是在技术面,难道面了个假阿里.不管怎么样,来篇面经攒攒人品. 二面 第一次遇到这么严肃的面试官,居然可以全程无表情的,面了这 ...
- 整数中1出现的次数(从1到n整数中1出现的次数)
整数中1出现的次数(从1到n整数中1出现的次数) 题目描述 求出1 ~ 13的整数中1出现的次数,并算出100 ~ 1300的整数中1出现的次数?为此他特别数了一下1 ~ 13中包含1的数字有1.10 ...
- java通过各种类型驱动连接数据库
常见数据库驱动实现类:JDBC-ODBC:sun.jdbc.odbc.JdbcOdbcDriver Oracle:oracle.jdbc.driver.OracleDriver MySQL:com.m ...
- vijos 1448 校门外的树 树状数组
描述 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的……如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作:K=1,K=1,读入l.r表 ...