hznu ti1050 programing list - files-cdn.cnblogs.com · hznu_ti1050 programing list build by dup4 at...

274
HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL1. STL-set 2. STL-vector 3. STL-string 4. STL-stack 5. STL-queue 6. STL-deque 7. STL-map 8. STL-bitset 9. STL-list 10. STL-heap 11. STL-奇淫巧技 字符串: 1. 编辑距离 2. 最短公共祖先 3. Karp-Rabin算法 4. strstr函数 5. Sunday Algorithm 6. AC自动机 7. 字符串HASH 8. 回文树 9. 后缀自动机 数论: 1. GCD 2. 线性方程组(高斯消元) 3. 模线性方程(组) 4. 素数相关 5. 合数相关 6. 组合数学相关 7. Polya计数 8. 最大1矩阵 9. 约瑟夫环问题 10. 博弈论 11. 周期性方程 12. 阶乘 13. 排列组合 14. 求逆元 15. FWT

Upload: others

Post on 21-Oct-2019

6 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

HZNU_TI1050 Programing list

Build by Dup4 at September 11, 2018

contents

STL:

1. STL-set2. STL-vector3. STL-string4. STL-stack5. STL-queue6. STL-deque7. STL-map8. STL-bitset9. STL-list

10. STL-heap11. STL-奇淫巧技

字符串:

1. 编辑距离2. 最短公共祖先3. Karp-Rabin算法4. strstr函数5. Sunday Algorithm6. AC自动机7. 字符串HASH8. 回文树9. 后缀自动机

数论:

1. GCD2. 线性方程组(高斯消元)3. 模线性方程(组)4. 素数相关5. 合数相关6. 组合数学相关7. Polya计数8. 最大1矩阵9. 约瑟夫环问题

10. 博弈论11. 周期性方程12. 阶乘13. 排列组合14. 求逆元15. FWT

Page 2: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

16. 整数划分17. 莫比乌斯反演18. 扩展Baby-Step Giant-Step19. 多项式求根20. 星期问题21. 汉诺塔22. 斐波那契数列23. 1/n循环节长度24. 矩阵相关25. 反素数26. 容斥27. 母函数28. BM递推

图论:

1. SPFA多源最短路径2. Floyd至少经过k条路3. 第K短路4. DSU on tree5. 最小生成树(森林)6. DAG的深度优先搜索标记7. 最大团问题8. 最小树形图9. 弦图判断

10. 弦图的PERFECT ELIMINATION点排列11. 稳定婚姻问题12. 拓扑排序13. 无向图连通分支14. 有向图强连通分支15. 有向图最小点基16. Floyd求最小环17. 树的重心18. 图Hash

网络流:

1. 二分图最小割2. 网络流3. 有上下界的流4. 最佳边割集5. 最佳点割集6. 最小边割集7. 最小点割集8. 最小覆盖问题

数据结构:

1. 左偏树2. 线段树扫描线3. 线段树位运算解决染色问题

Page 3: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

4. 线段树动态开点5. 可持久化线段树6. 动态开点主席树7. 线段树找区间内第一个大于某个数的数8. 动态维护最长上升子序列9. 并查集

10. 可持久化并查集11. Trie树12. 二分查找13. 树状数组14. 滚动数组15. 堆栈16. 块状链表17. 主席树求区间第k大多维护sum18. LCA倍增维护距离

计算几何:

1. Andrew求凸包2. 判断四点共面3. 求多边形重心4. 旋转卡壳

其他:

1. C++Head2. JavaHead3. C++数学函数4. Java-BigInteger5. Java-Decimal6. Java-奇淫巧技7. 最长递增子序列8. 最长公共子序列9. 最长公共递增子序列

10. 机器工作调度11. 最少找硬币问题12. 棋盘分割13. 区间最大频率14. 使序列有序的最少交换次数15. 背包相关16. 树的前序中序转后序17. 过桥问题&倒水问题18. 多项式19. 中缀表达式求值20. 对拍程序21. TSP旅行商问题22. 二分高精度开方以及多次方23. Vim相关设置

Page 4: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

STL STL-set

STL-vector

s.begin()       // 返回指向第一个元素的迭代器s.clear()       // 清除所有元素s.count()       // 返回某个值元素的个数s.empty()       // 如果集合为空,返回true(真)s.end()         // 返回指向最后一个元素之后的迭代器,不是最后一个元素s.equal_range() // 返回集合中与给定值相等的上下限的两个迭代器s.erase()       // 删除集合中的元素s.find()        // 返回一个指向被查找到元素的迭代器s.get_allocator()   // 返回集合的分配器s.insert()      // 在集合中插入元素s.lower_bound() // 返回指向大于(或等于)某值的第一个元素的迭代器s.key_comp()    // 返回一个用于元素间值比较的函数s.max_size()    // 返回集合能容纳的元素的最大限值s.rbegin()      // 返回指向集合中最后一个元素的反向迭代器s.rend()        // 返回指向集合中第一个元素的反向迭代器s.size()        // 集合中元素的数目s.swap()        // 交换两个集合变量s.upper_bound() // 返回大于某个值元素的迭代器s.value_comp()  // 返回一个用于比较元素间的值的函数//multiset和set的基本操作相似,需要注意的是,集合的count()能返回0(无)或者1(有),而多重集合是有多少个返回多少个。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

vector<int> s;      

// 定义一个空的vector对象,存储的是int类型的元素vector<int> s(n);  

// 定义一个含有n个int元素的vector对象vector<int> s(first, last);

// 定义一个vector对象,并从由迭代器first和last定义的序列[first, last)中复制初值s[i]                // 直接以下标方式访问容器中的元素s.at(i)             // at访问会检查是否越界,是则抛出 out of range 异常s.front()           // 返回首元素s.back()            // 返回尾元素s.push_back(x)      // 向表尾插入元素x

s.size()            // 返回表长s.empty()           // 表为空时,返回真,否则返回假s.pop_back()        // 删除表尾元素s.begin()           // 返回指向首元素的随机存取迭代器s.end()             // 返回指向尾元素的下一个位置的随机存取迭代器s.insert(it, val)   // 向迭代器it指向的元素前插入新元素val

s.insert(it, n, val)// 向迭代器it指向的元素前插入n个新元素val

s.insert(it, first, last)  

// 将由迭代器first和last所指定的序列[first, last)插入到迭代器it指向的元素前面s.erase(it)         // 删除由迭代器it所指向的元素s.erase(first, last)// 删除由迭代器first和last所指定的序列[first, last)

s.reserve(n)        // 预分配缓冲空间,使存储空间至少可容纳n个元素

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

Page 5: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

STL-string

s.resize(n)         // 改变序列长度,超出的元素将会全部被删除,如果序列需要扩展(原空间小于n),元素默认值将填满扩展出的空间s.resize(n, val)    // 改变序列长度,超出的元素将会全部被删除,如果序列需要扩展(原空间小于n),val将填满扩展出的空间s.shrink_to_fit()   // 减少容器大小直到刚好能够满足元素所占存储空间大小s.clear()           // 删除容器中的所有元素s.swap(v)           // 将s与另一个vector对象进行交换s.assign(first, last)

reverse(first, last)//将容器中元素反转// 将序列替换成由迭代器first和last所指定的序列[first, last),[first, last)不能是原序列中的一部分// 要注意的是,resize操作和clear操作都是对表的有效元素进行的操作,但并不一定会改变缓冲空间的大小// 另外,vector还有其他的一些操作,如反转、取反等,不再一一列举

// vector上还定义了序列之间的比较操作运算符(>、<、>=、<=、==、!=),可以按照字典序比较两个序列。

24

25

26

27

28

29

30

31

32

33

34

//string类构造函数string(const char *s)       //用c字符串s初始化string(int n, char c)       //用n个字符c初始化//默认构造函数  

string s1; s1 = "hello"; s2 = "world!"; s1 += s2;

//string类字符操作const char &operator[](int n)const;

const char &at(int n)const;

char &operator[](int n);

char &at(int n);

//operator[]和at()均返回当前字符串中第n个字符的位置,但at函数提供范围检查,当越界时会抛出out_of_range异常,下标运算符[]不提供检查访问。const char *data()const;   //返回一个非null终止的c字符数组const char *c_str()const;  //返回一个以null终止的c字符串int copy(char *s, int n, int pos = 0) const;

//把当前串中以pos开始的n个字符拷贝到以s为起始位置的字符数组中,返回实际拷贝的数目

//string的特性描述int capacity()const;        //返回当前容量(即string中不必增加内存即可存放的元素个数)int max_size()const;        //返回string对象中可存放的最大字符串的长度int size()const;            //返回当前字符串的大小int length()const;          //返回当前字符串的长度bool empty()const;          //当前字符串是否为空void resize(int len,char c);//把字符串当前大小置为len,并用字符c填充不足的部分

//string类的输入输出操作//string类重载运算符operator>>用于输入,同样重载运算符operator<<用于输出操作//函数getline(istream &in,string &s);用于从输入流in中读取字符串到s中,以换行符'\n'分开

//string的赋值string &operator=(const string &s);                   //把字符串s赋给当前字符串string &assign(const char *s);                        //用c类型字符串s赋值string &assign(const char *s,int n);                  //用c字符串s开始的n个字符赋值string &assign(const string &s);                      //把字符串s赋给当前字符串

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

Page 6: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

string &assign(int n,char c);                         //用n个字符c赋值给当前字符串string &assign(const string &s,int start,int n);      //把字符串s中从start开始的n个字符赋给当前字符串string &assign(const_iterator first,const_itertor last);//把first和last迭代器之间的部分赋给字符串

//string的连接string &operator+=(const string &s);          //把字符串s连接到当前字符串的结尾string &append(const char *s);                //把c类型字符串s连接到当前字符串结尾string &append(const char *s,int n);          //把c类型字符串s的前n个字符连接到当前字符串结尾string &append(const string &s);              //同operator+=()

string &append(const string &s,int pos,int n);//把字符串s中从pos开始的n个字符连接到当前字符串的结尾string &append(int n,char c);                 //在当前字符串结尾添加n个字符c

string &append(const_iterator first,const_iterator last);

//把迭代器first和last之间的部分连接到当前字符串的结尾

//string的比较bool operator==(const string &s1,const string &s2)const;    //比较两个字符串是否相等//运算符">","<",">=","<=","!="均被重载用于字符串的比较;int compare(const string &s) const;                         //比较当前字符串和s的大小int compare(int pos, int n,const string &s)const;

//比较当前字符串从pos开始的n个字符组成的字符串与s的大小int compare(int pos, int n,const string &s,int pos2,int n2)const;

//比较当前字符串从pos开始的n个字符组成的字符串与s中pos2开始的n2个字符组成的字符串的大小int compare(const char *s) const;

int compare(int pos, int n,const char *s) const;

int compare(int pos, int n,const char *s, int pos2) const;

//compare函数在>时返回1,<时返回-1,==时返回0  

//string的子串string substr(int pos = 0,int n = npos) const;//返回pos开始的n个字符组成的字符串

//string的交换void swap(string &s2);                        //交换当前字符串与s2的值

//string类的查找函数int find(char c, int pos = 0) const;           //从pos开始查找字符c在当前字符串的位置int find(const char *s, int pos = 0) const;    //从pos开始查找字符串s在当前串中的位置int find(const char *s, int pos, int n) const; //从pos开始查找字符串s中前n个字符在当前串中的位置int find(const string &s, int pos = 0) const;  //从pos开始查找字符串s在当前串中的位置//查找成功时返回所在位置,失败返回string::npos的值int rfind(char c, int pos = npos) const;       //从pos开始从后向前查找字符c在当前串中的位置int rfind(const char *s, int pos = npos) const;

int rfind(const char *s, int pos, int n = npos) const;

int rfind(const string &s,int pos = npos) const;

//从pos开始从后向前查找字符串s中前n个字符组成的字符串在当前串中的位置,成功返回所在位置,失败时返回string::npos的值int find_first_of(char c, int pos = 0) const;  //从pos开始查找字符c第一次出现的位置int find_first_of(const char *s, int pos = 0) const;

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

Page 7: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

int find_first_of(const char *s, int pos, int n) const;

int find_first_of(const string &s,int pos = 0) const;

//从pos开始查找当前串中第一个在s的前n个字符组成的数组里的字符的位置。查找失败返回string::npos

int find_first_not_of(char c, int pos = 0) const;

int find_first_not_of(const char *s, int pos = 0) const;

int find_first_not_of(const char *s, int pos,int n) const;

int find_first_not_of(const string &s,int pos = 0) const;

//从当前串中查找第一个不在串s中的字符出现的位置,失败返回string::npos

int find_last_of(char c, int pos = npos) const;

int find_last_of(const char *s, int pos = npos) const;

int find_last_of(const char *s, int pos, int n = npos) const;

int find_last_of(const string &s,int pos = npos) const;

int find_last_not_of(char c, int pos = npos) const;

int find_last_not_of(const char *s, int pos = npos) const;

int find_last_not_of(const char *s, int pos, int n) const;

int find_last_not_of(const string &s,int pos = npos) const;

//find_last_of和find_last_not_of与find_first_of和find_first_not_of相似,只不过是从后向前查找

//string类的替换函数string &replace(int p0, int n0,const char *s);

//删除从p0开始的n0个字符,然后在p0处插入串s

string &replace(int p0, int n0,const char *s, int n);

//删除p0开始的n0个字符,然后在p0处插入字符串s的前n个字符string &replace(int p0, int n0,const string &s);

//删除从p0开始的n0个字符,然后在p0处插入串s

string &replace(int p0, int n0,const string &s, int pos, int n);

//删除p0开始的n0个字符,然后在p0处插入串s中从pos开始的n个字符string &replace(int p0, int n0,int n, char c);

//删除p0开始的n0个字符,然后在p0处插入n个字符c

string &replace(iterator first0, iterator last0,const char *s);

//把[first0,last0)之间的部分替换为字符串s

string &replace(iterator first0, iterator last0,const char *s, int n);

//把[first0,last0)之间的部分替换为s的前n个字符string &replace(iterator first0, iterator last0,const string &s);

//把[first0,last0)之间的部分替换为串s

string &replace(iterator first0, iterator last0,int n, char c);

//把[first0,last0)之间的部分替换为n个字符c

string &replace(iterator first0, iterator last0,const_iterator first,

const_iterator last);

//把[first0,last0)之间的部分替换成[first,last)之间的字符串

//string类的插入函数string &insert(int p0, const char *s);

string &insert(int p0, const char *s, int n);

string &insert(int p0,const string &s);

string &insert(int p0,const string &s, int pos, int n);

//前4个函数在p0位置插入字符串s中pos开始的前n个字符string &insert(int p0, int n, char c);  //此函数在p0处插入n个字符c

iterator insert(iterator it, char c);   //在it处插入字符c,返回插入后迭代器的位置void insert(iterator it, const_iterator first, const_iterator last);

//在it处插入[first,last)之间的字符void insert(iterator it, int n, char c);//在it处插入n个字符c

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

Page 8: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

STL-stack

STL-queue

//string类的删除函数iterator erase(iterator first, iterator last);

//删除[first,last)之间的所有字符,返回删除后迭代器的位置iterator erase(iterator it);             //删除it指向的字符,返回删除后迭代器的位置string &erase(int pos = 0, int n = npos);//删除pos开始的n个字符,返回修改后的字符串

//string类的迭代器处理//string类提供了向前和向后遍历的迭代器iterator,迭代器提供了访问各个字符的语法,类似于指针操作,迭代器不检查范围。//用string::iterator或string::const_iterator声明迭代器变量,const_iterator不允许改变迭代的内容。常用迭代器函数有:const_iterator begin()const;

iterator begin();                  //返回string的起始位置const_iterator end()const;

iterator end();                    //返回string的最后一个字符后面的位置const_iterator rbegin()const;

iterator rbegin();                 //返回string的最后一个字符的位置const_iterator rend()const;

iterator rend();                   //返回string第一个字符位置的前面//rbegin和rend用于从后向前的迭代访问,通过设置迭代器string::reverse_iterator,string::const_reverse_iterator实现

//字符串流处理:通过定义ostringstream和istringstream变量实现,#include <sstream>头文件中例如:    string input("hello,this is a test");

   istringstream is(input);

   string s1,s2,s3,s4;

   is>>s1>>s2>>s3>>s4;//s1="hello,this",s2="is",s3="a",s4="test"

   ostringstream os;

   os<<s1<<s2<<s3<<s4;

   cout<<os.str();

stringstream ss; string s;

getline(cin, s);

ss << s;

while (ss >> s);

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

s.push(x);  // 入栈s.pop();    // 出栈s.top();    // 访问栈顶s.empty();  // 当栈空时,返回true

s.size();   // 访问栈中元素个数

1

2

3

4

5

q.push(x);  // 入队列q.pop();    // 出队列q.front();  // 访问队首元素

1

2

3

Page 9: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

STL-deque

q.back();   // 访问队尾元素q.empty();  // 判断队列是否为空q.size();   // 访问队列中的元素个数//STL-priority_queue

priority_queue<int> q;

priority_queue<pair<int, int> > qq;                

//注意在两个尖括号之间一定要留空格,防止误判priority_queue<int, vector<int>, greater<int> > qqq; //定义小的先出队列//如果想要按照顺序从小到大出队列,只需要改动比较运算符重载为:inline bool operator < (const node &r) const

{

   return w > r.w;

}

4

5

6

7

8

9

10

11

12

13

14

15

16

/*

deque: 是一个double-ended queue,

   1)支持随即存取,也就是[]操作符,    2)支持两端操作,push(pop)-back(front),在两端操作上与list效率差不多

   因此在实际使用时,如何选择这三个容器中哪一个,应根据你的需要而定,一般应遵循下面的原则:    1、如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector

   2、如果你需要大量的插入和删除,而不关心随即存取,则应使用list

   3、如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。说明

#include <deque> deque容器类与vector类似,支持随机访问和快速插入删除,它在容器中某一位置上的操作所花费的是线性时间。与vector不同的是,deque还支持从开始端插入数据:push_front()。*/

//构造:deque<Elem> c           //创建一个空的deque

deque<Elem> c1(c2)      //复制一个deque。deque<Elem> c(n)        //创建一个deque,含有n个数据,数据均已缺省构造产生。deque<Elem> c(n, elem)  //创建一个含有n个elem拷贝的deque

deque<Elem> c(beg,end)  //创建一个以[beg;end)区间的deque

c.~deque<Elem>()        //销毁所有数据,释放内存

//方法:

c.assign(beg,end) //将[beg; end)区间中的数据赋值给c。c.assign(n,elem) //将n个elem的拷贝赋值给c。c. at(idx) //传回索引idx所指的数据,如果idx越界,抛出out_of_range。c.back() //传回最后一个数据,不检查这个数据是否存在。c.begin() //传回迭代器中的第一个数据。c.clear() //移除容器中所有数据。c.empty() //判断容器是否为空。c.end() //指向迭代器中的最后一个数据地址。c.erase(pos) //删除pos位置的数据,传回下一个数据的位置。c.erase(beg,end) //删除[beg,end)区间的数据,传回下一个数据的位置。c.front() //传回第一个数据。get_allocator //使用构造函数返回一个拷贝。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

Page 10: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

c.insert(pos,elem) //在pos位置插入一个elem拷贝,传回新数据位置c.insert(pos,n,elem) //在pos位置插入>n个elem数据。无返回值c.insert(pos,beg,end)    //在pos位置插入在[beg,end)区间的数据。无返回值c.max_size() //返回容器中最大数据的数量。c.pop_back() //删除最后一个数据。c.pop_front() //删除头部数据。c.push_back(elem) //在尾部加入一个数据。c.push_front(elem) //在头部插入一个数据。c.rbegin() //传回一个逆向队列的第一个数据。c.rend() //传回一个逆向队列的最后一个数据的下一个位置。c.resize(num) //重新指定队列的长度。c.size() //返回容器中实际数据的个数。c1.swap(c2) or swap(c1,c2)  //将c1和c2元素互换。

/*

简介deque双端队列容器(double-ended queue)与vector非常相似 算法的时间复杂度也是常数阶O(1)

deque内部的数据机制和执行性能与vector不同 一般说来,当考虑到容器元素的内存分配策略和操作的性能时

deque相对vector较为有优势

deque双端队列采用分块的线性结构来存储数据 具有高效的删除首尾元素的函数 由于deque容器是以deque块为单位进行内存的分配 并使用了二级的Map进行管理

因此不容易实现类似于vector的 capacity 和 reverse函数 而且deque容器也不需要这样的获取和调整容器大小的函数*/

//deque应用基础

//创建deque对象:1、deque()

//创建一个空的deque对象 如:deque<int> d;

2、deque(size_type n)

//创建一个具有n个元素的deque对象,每个deque元素具有它的类型下的默认值 如:deque<int> d(10);

3、deque(size_type n, const T& value)

//创建一个具有n个元素的deque对象,每个元素具有初始值value 如:deque<int> d(10, 5);

4、deque(const deque&)

//通过拷贝一个deque对象的各个元素值,创建一个新的deque对象 如:deque<int> d1(10, 5);

deque<int> d2(d1);

5、 deque(const InputIterator first, const InputIterator last, const A& a=A())

//通过拷贝迭代器区间[first, last)的元素值,创建一个新的deque对象中,内存分配器可省略 如:int

iArray[] = {1,2,3}; deque<int> d(iArray, iArray+3);

//初始化赋值://deque提供的push_back函数常用来进行deque容器的初始化,push_back函数在容器的尾端插入新元素value。void push_back(const T&)

//元素的遍历访问://deque的元素可采用数组或迭代器的方式进行遍历访问。

//元素的插入://由于deque使用了两个迭代器分别指向双端队列的首尾,因此deque具有高效的头部插入元素的函数push_front()

void push_front(const T&)

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

Page 11: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

STL-map

STL-bitset

//其它位置的插入,将涉及相关元素的移位拷贝,insert函数的一个较常用的原型为:iterator insert(iterator pos, const T& x)

//元素的删除:void pop_front() 删除deque的第一个元素void pop_back() 删除deque的最后一个元素iterator erase(iterator pos) 删除迭代器pos所指的元素iterator erase(iterator first, iterator last) 删除迭代器区间[first, last)的所有元素void clear() 调用erase函数,清除所有元素

//元素的反向遍历:reverse_iterator rbegin()

reverse_iterator rend()

//deque的交换:void swap(deque&)

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

map <int, int> mp;

mp.begin() //返回指向map头部的迭代器mp.clear() //删除所有元素mp.count() //返回指定元素出现的次数mp.empty() //如果map为空则返回true  

mp.end()            //返回指向map末尾的迭代器mp.equal_range()    //返回特殊条目的迭代器对mp.erase()          //删除一个元素mp.find()           //查找一个元素mp.get_allocator()  //返回map的配置器mp.insert()         //插入元素mp.key_comp()       //返回比较元素key的函数mp.lower_bound()    //返回键值>=给定元素的第一个位置mp.max_size()       //返回可以容纳的最大元素个数mp.rbegin()         //返回一个指向map尾部的逆向迭代器mp.rend()           //返回一个指向map头部的逆向迭代器mp.size()           //返回map中元素的个数mp.swap()           //交换两个map

mp.upper_bound()    //返回键值>给定元素的第一个位置mp.value_comp()     //返回比较元素value的函数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

const int MAXN = 32;

bitset<MAXN> bt;            

//bt 包括 MAXN 位,下标 0 ~ MAXN - 1,默认初始化为 0

bitset<MAXN> bt1(0xf);      

//0xf 表示十六进制数 f,对应二进制 1111,将 bt1 低 4 位初始化为 1

bitset<MAXN> bt2(012);      

//012 表示八进制数 12,对应二进制 1010,即将 bt2 低 4 位初始化为 1010

bitset<MAXN> bt3("1010");  

//将 bt3 低 4 位初始化为 1010

1

2

3

4

5

6

7

8

9

Page 12: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

STL-list

STL-heap

bitset<MAXN> bt4(s, pos, n);

//将 01 字符串 s 的 pos 位开始的 n 位初始化 bt4

bt.any()        // bt 中是否存在置为 1 的二进制位?bt.none()       // bt 中不存在置为 1 的二进制位吗?bt.count()      // bt 中置为 1 的二进制位的个数bt.size()       // bt 中二进制位的个数bt[pos]         // 访问 bt 中在 pos 处的二进制位bt.test(pos)    // bt 中在 pos 处的二进制位是否为 1

bt.set()        // 把 bt 中所有二进制位都置为 1

bt.set(pos)     // 把 bt 中在 pos 处的二进制位置为 1

bt.reset()      // 把 bt 中所有二进制位都置为 0

bt.reset(pos)   // 把 bt 中在pos处的二进制位置为0

bt.flip()       // 把 bt 中所有二进制位逐位取反bt.flip(pos)    // 把 bt 中在 pos 处的二进制位取反bt[pos].flip()  // 同上bt.to_ulong()   // 用 bt 中同样的二进制位返回一个 unsigned long 值os << bt        // 把 bt 中的位集输出到 os 流bt.to_string()  // 返回bitset的字符串形式

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

assign() //给list赋值

back() //返回最后一个元素

begin() //返回指向第一个元素的迭代器

clear() //删除所有元素

empty() //如果list是空的则返回true

end() //返回末尾的迭代器

erase() //删除一个元素

front() //返回第一个元素

get_allocator() //返回list的配置器

insert() //插入一个元素到list中

max_size() //返回list能容纳的最大元素数量

merge() //合并两个list

pop_back() //删除最后一个元素

pop_front() //删除第一个元素

push_back() //在list的末尾添加一个元素

push_front() //在list的头部添加一个元素

rbegin() //返回指向第一个元素的逆向迭代器

remove() //从list删除元素

remove_if() //按指定条件删除元素

rend() //指向list末尾的逆向迭代器

resize() //改变list的大小

reverse() //把list的元素倒转

size() //返回list中的元素个数

sort() //给list排序

splice() //合并两个list

swap()    //交换两个list

unique() //删除list中重复的元素

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

Page 13: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

STL-奇淫巧技

/*

C++中堆的应用:make_heap, pop_heap, push_heap, sort_heap

函数说明:std::make_heap将[start, end)范围进行堆排序,默认使用less, 即最大元素放在第一个。

std::pop_heap 将front(即第一个最大元素)移动到end的前部,同时将剩下的元素重新构造成(堆排序)一个新的heap。

std::push_heap对刚插入的(尾部)元素做堆排序。

std::sort_heap将一个堆做排序,最终成为一个有序的系列,可以看到sort_heap时,必须先是一个堆(两个特性:1、最大元素在第一个 2、添加或者删除元素以对数时间),因此必须先做一次make_heap.

make_heap, pop_heap, push_heap, sort_heap都是标准算法库里的模板函数,用于将存储在vector/deque 中的元素进行堆操作,对不愿自己写数据结构堆的C++选手来说,这几个算法函数很有用,下面是这几个函数操作vector中元素的例子*/

#include<iostream>

#include<algorithm>

#include<vector>

using namespace std;

void print_ivec(vector<int>::iterator begin, vector<int>::iterator end)

{

   for(;begin != end; ++begin)

       cout << *begin << '\t';

   cout << endl;

}

int main(int argc, char* argv[])

{

   int a[] = {1, 12, 15, 20, 30};

   vector<int> ivec(a, a + sizeof(a) / sizeof(a[0]));

   print_ivec(ivec.begin(), ivec.end());

   make_heap(ivec.begin(), ivec.end(), greater<int>());

   print_ivec(ivec.begin(), ivec.end());

   pop_heap(ivec.begin(), ivec.end());

   ivec.pop_back();

   print_ivec(ivec.begin(), ivec.end());

   ivec.push_back(99);

   push_heap(ivec.begin(), ivec.end());

   print_ivec(ivec.begin(), ivec.end());

   sort_heap(ivec.begin(), ivec.end());

   print_ivec(ivec.begin(), ivec.end());

   return 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

//cctype

isalpha(c) //判断字符c是否是字母.

isupper(c) //判断字符c是否是大写字母.

islower(c) //判断字符c是否是小写字母.

1

2

3

4

Page 14: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

isdigit(c) //判断字符c是否是数字字符.

isspace(c) //判断字符c是否是空格,换行符或者tab.

//deque

q.push_back(x) //在双端队列q的队尾加入一个元素x.

q.push_front(x) //在双端队列q的队头加入一个元素x

q.pop_back() //弹出队尾的元素.

q.pop_front() //弹出队头的元素.

q.front() //队头的元素.

q.back() //队尾的元素.

#include<bits/stdc++.h> //Ithea Myse Valgulious

} using namespace chtholly; //省略快读快写using namespace std;

const int yuzu=2e6;

int a[yuzu|10];

deque<int> q;

int main()

{

   int i,n=read(),m=read();

   for (i=1; i<=n; ++i)

  {

       a[i]=read();

       printf("%d\n",a[q.front()]);

       for (; !q.empty()&&i-m>=q.front(); q.pop_front());

       for (; !q.empty()&&a[i]<=a[q.back()]; q.pop_back());

       q.push_back(i);

  }

}

//string

/*

虽然字符串的类型非常骚,但是常用的没这么多,所以知道那些就可以了.

不过还是有两个神技被大部分人忽略了.

第一个叫std::to_string.

这个函数能够把数字(可以是整形数,也可以是浮点数)直接转换成字符串.

真的非常好用,我们看看例题.

给出一个长度为偶数的正整数n,判断它前一半位数的数字之和是否等于后一半. n<=1e9.

*/

#include<bits/stdc++.h>

using namespace std;

int main()

{

   int ans=0;

   int n;

   cin>>n;

   string a=to_string(n);

   for (int i=0; i<a.size(); ++i)

  {

       if (i<a.size()/2) ans+=a[i];

       else ans-=a[i];

  }

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

Page 15: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

   puts(ans==0?"Yes":"No");

}

stoi() //Convert string to integer

stol() //Convert string to long int

stoul() //Convert string to unsigned int

stoll() //Convert string to long long

stoull() //Convert string to unsigned long long

stof() //Convert string to float

stod() //Convert string to double

stold() //Convert string to long double

   

//algorithm

/*

这个头文件里骚的东西真的多.

next_permutation,prev_permutation.

这两个东西有多厉害不用我说吧,枚举全排列就靠它了.

min_element,max_element,

返回范围中最小/最大元素的迭代器.

fill(iterator first,iterator last,val)

你是不是怕memset出一些奇怪的问题?用fill!.

nth_element(it first,it nth,it last),

能让第n

大的元素处在区间的第n个.

unique(it first,it last);

将区间去重(注意只能对连续相同的元素去重)并返回元素的个数的位置指向的迭代器.

所以如果要达到真实去重的效果请对区间排序.

最后是神奇的random_shuffle,也就是随机化区间内的所有元素了.

*/

   

//ctime

/*

时间!关于日期和时间的计算在信息学竞赛中非常重要.

这一次我来介绍一下ctime中两个神奇的函数.

1:clock

这个东西可以算代码运行的时间.用法是这样的:

*/

//1:clock

clock_t nowtime=clock();

...

cout<<clock()-nowtime<<endl;

/*

这时候输出了一个数字,单位是毫秒,表示运行的时间.

这样就可以判断你是不是tle了.

爆搜到时限之后直接输出−1其实也是用的这种方法.

*/

//2.difftime

/*

这个函数用来算两个时间之间的时间差.

用法?

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

Page 16: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

首先在c++中,时间是由一个叫tm的结构体储存的.

这个结构体有9个成员.

*/

struct tm

{

   int tm_sec;//秒    int tm_min;//分钟    int tm_hour;//小时    int tm_mday;//(这个月的)哪一天    int tm_mon;//月    int tm_year;//年(这个年是以1900作为起始时间的,设置的时候要减去1900)

   int tm_wday;//星期几,0表示星期天    int tm_yday;//今年从1月1日开始的第几天    int tm_isdst;//是否是夏令时};

/*

然后有一个函数mktime(&t) 可以将结构体表示的时间变为秒表示的时间.

接下来用difftime函数可以算出两个日期之间差的秒数,除以86400就是天数.

举例计算从今年7月22日(谁的生日?) 到今天 (7月27日) 的天数.应该是5天.

*/

/*

要注意的点:

1.年份从1900开始,月份以1月为准,要减掉1;

2.计算的时间的范围在[1900,3000]之间.别过界了.

*/

//stringstream

/*

stringstream的头文件是<sstream>.

终于到压轴的神器出场了.这是我不得不对c++顶礼膜拜的原因之一.

它的适用范围很广(面对毒瘤出题人)

而我仅仅是挖开了冰山一角.

我们来看例题.

洛谷p1020 导弹拦截 这题题目不难,我们就看它的输入.

想必大家都是while (scanf("%d",&n)!=EOF){}之类的读法.

现在我们把题目改一下.

本题包含多组数据,每行一组,包含若干个数字.

这下完了.

你不给我数据组数就算了,每组数据也不给我多少个数字,我怎么读啊!

sb出题人,*************(已被屏蔽)

这题从读入上就已经干倒了一群人.

那么该怎么办呢?

考虑用getchar(),碰到空格换一个数字,碰到回车换一组数据.

非常麻烦.

那用getline,每次读入一组数据,用奇怪的方法搞来搞去.

还是很麻烦.

这时候stringstream出场了.

*/

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

Page 17: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

const int yuzu=1e5;

int a[yuzu|10],n;

int main()

{

   string s;

   for (; getline(cin,s);)

  {

       stringstream llx(s);

       n=0;

       for (; llx>>a[++n];);

  }

}

/*

字符串流也是流的一种,可以用来输入.上题就是一种可能的方法.

那么还有一个问题也可以迎刃而解.

给出一串用奇怪符号(里面包括空格)隔开的数字,输出它们的和.

样例:

*/

/*

input:

{15/;; ;8787*- )),|^&&1<<>>}

output:

8803

*/

/*

在get字符串以后把里面不是数字的符号都变成空格,然后用stringstream输入就可以了.

配合c++11中的遍历方法和cctype头文件使得代码非常简洁.

for (char &c:s) if (!isdigit(c)) c=' ';

*/

//c++输出#include <iomanip>

//关闭同步ios::sync_with_stdio(false);

cin.tie(0); cout.tie(0);

//输出以小数形式而非科学计数法cout << fixed;

cout.precision(10);

//格式化输出cout.setf(ios::right); //靠右 left 靠左cout.fill('0');        // 填充物cout.width(3);         // 宽度

//c输出//对齐printf("%-5d\n%-5d", a, b); 左对齐 无负号  右对齐//出现在输入输出函数中的%*c ,作用是在输入或输出时,跳过一个变量,例如:void main()

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

Page 18: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

字符串 编辑距离

{

 int i=1,j=2,k=3;

 printf("%d,%*d,%d\n",i,j,k,i);//遇到%*d,就把j跳过了,输出k,故后面应该放4个变量}

//程序的输出结果是1, 3,1 (如果出现跳过变量的情况,跳过的变量用空格代替,因此3前面多一个空格;//保留任意位小数,即位数由输入指定printf("%.*f\n", d, v);

// d 为位数

217

218

219

220

221

222

223

224

225

/*

编辑距离,又称Levenshtein距离(也叫做Edit Distance)是指两个字串之间,由一个转成另一个所需的最少编辑操作次数许可的编辑操作包括将一个字符替换成另一个字符 插入一个字符 删除一个字符。

*/

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 1e3 + 5;

int T, cas = 0;

int n, m;

int dp[N][N];

char s[N], t[N];

int main()

{

   while (scanf("%s%s", s, t) != EOF)

  {

       int n = (int)strlen(s), m = (int)strlen(t);

       for (int i = 0; i <= n; i++)

      {

           dp[i][0] = i;

      }

       for (int i = 0; i <= m; i++)

      {

           dp[0][i] = i;

      }

       for (int i = 1; i <= n; i++)

      {

           for (int j = 1; j <= m; j++)

          {

               dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + 1;

               dp[i][j] = min(dp[i][j], dp[i - 1][j - 1] + (s[i - 1] != t[j -

1]));

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

Page 19: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

最短公共祖先

          }

      }

       printf("%d\n", dp[n][m]);

  }

   return 0;

}

37

38

39

40

41

42

43

/*

将KMP进行略微的改动,依然是查找匹配段,要求要么一个串包含另一个串,要么一个串的前缀等于另一个串的后缀。

多个短字符串首先用一个数组save[i][j]来保存第j个串加在第i个串之后,第i个串所增加的长度,比如alba bacau,把bacau加在alba后alba所增加的长度就为3.我们采用搜索的策略,以每一个串为第一个串进行搜索for(i = 1;

i <= n; i++) {dfs(i)}// 以第i个串为第一个串进行搜索。 剪枝:主要是在搜索过程中,当前面一些串的长度比当前已经找到的min还大的话就剪去该枝。*/

/*

* The shortest common superstring of 2 strings S1 and S2 is

* a string S with|the minimum number of characters which

* contains both S1 and S2 as a sequence of consecutive characters.

*/

const int N = 1000005;

char t[N],w[N];

int i,j,Next[N],sum,l;

void get_next(char *a,int len)

{

Next[0]=-1;

i=0;j=-1;

while(i<len)

  {

if(j==-1||a[i]==a[j]) Next[++i]=++j;

else j=Next[j];

}

}

int KMP(char *a,char *b)

{

int lena=strlen(a);

int lenb=strlen(b);

get_next(b,lenb);

i=0;j=0;

while(i<lena&&j<lenb)

  {

if(j==-1||b[j]==a[i]) i++,j++;

else j=Next[j];

}

return j;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

Page 20: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

Karp-Rabin算法

int main()

{

int n;

scanf("%d",&n);

while(n--)

  {

scanf("%s%s",&w,&t);

//w主串 int a=KMP(w,t);

//printf("%d\n",a);

int b=KMP(t,w);

//printf("%d\n",b);

printf("%d\n",strlen(w)+strlen(t)-max(a,b));

}

return 0;

}

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

//字符串匹配/*

* hash(w[0 ... m - 1]) =

* (w[0] * 2 ^ (m - 1) + ... + w[m - 1] * 2 ^ 0) % q;

* hash(w[j + 1 ... j + m]) =

* rehash(y[j], y[j + m], hash(w[j ... j + m - 1]);

* rehash(a, b, h) = ((h - a * 2 ^ (m - 1)) * 2 + b) % q;

* 可以用q = 2 ^ 32简化%运算 */

#define REHASH(a, b, h) (((h - (a) * b) << 1) + b)

int krmatch(char *x, int m, char *y, int n)

{

   //search x in y

   int d, hx, hy, i, j;

   for (d = i = 1; i < m; i++)

       d = (d << 1);

   for (hy = hx = i = 0; i < m; i++)

  {

       hx = ((hx << 1) + x[i]);

       hy = ((hy << 1) + y[i]);

  }

   for (j = 0; j <= n - m; j++)

  {

       if (hx == hy && memcmp(x, y + j, m) == 0)

           return j;

       hy = REHASH(y[j], y[j + m], hy);

  }

   return 0;   //理论上不会背执行,全部都应该从上一个return返回}

//字符块匹配/*

* Text: n * m matrix;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

Page 21: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

* Pattern: x * y matrix;

*/

//#define uint unsigned int // C++中自带const int A = 1024, B = 128;

const uint E = 27;

char text[A][A];

char patt[B][B];

uint ht, hp;

uint pw[B * B];

uint hor[A];

uint ver[A][A];

int n, m, x, y;

void init()

{

   int i, j = B * B;

   for (i = 1, pw[0] = 1; i < j; i++)

       pw[i] = pw[i - 1] * E;

   return ;

}

void hash()

{

   int i, j;

   for (i = 0; i < n; i++)

       for (j = 0, hor[i] = 0; j < y; j++)

      {

           hor[i] *= pw[x];

           hor[i] += text[i][j] - 'a';

      }

   for (j = 0; j < m; j++)

  {

       for (i = 0, ver[0][j] = 0; i < x; i++)

      {

           ver[0][j] *= E;

           ver[0][j] += text[i][j] - 'a';

      }

       for (i = 1; i <= n - x; i++)

      {

           ver[i][j] = (ver[i - 1][j] - (text[i - 1][j] - 'a') * pw[x - 1]) * E +

text[i + x - 1][j] - 'a';

      }

  }

   for (j = 0, ht = hp = 0; j < y; j++)

  {

       for (i = 0; i < x; i++)

      {

           ht *= E;

           ht += text[i][j] - 'a';

           hp *= E;

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

Page 22: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

strstr函数

           hp += patt[i][j] - 'a';

      }

  }

   return ;

}

void read()

{

   int i;

   std::cin >> n >> m;

   for (i = 0; i < n; i++)

       std::cin >> text[i];

   for (i = 0; i < x; i++)

       std::cin >> patt[i];

   return ;

}

int solve()

{

   if (n == 0 || m == 0 || x == 0 || y == 0)

       return 0;

   int i, j, cnt = 0;

   uint t;

   for (i = 0; i <= n - x; i++)

  {

       for (j = 0, t = ht; j <= m - y; j++)

      {

           if (t == hp)

               cnt++;

           t = (t - ver[i][j] * pw[y * x - x]) * pw[x] + ver[i][j + y];

      }

       ht = (ht - hor[i] * pw[x - 1]) * E + hor[i + x];

  }

   return cnt;

}

int main(int argc, const char * argv[])

{

   int T;

   init();

   for (std::cin >> T; T; T--)

  {

       read();

       hash();

       std::cout << solve() << '\n';

  }

   return 0;

}

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

Page 23: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

Sunday 算法

/*

* strstr函数 * 功能:在串中查找指定字符串的第一次出现 * 用法:char *strstr(char *strOne, char *strTwo);

* 据说strstr函数和KMP的算法效率差不多 */

int main(int argc, const char * argv[])

{

   char strOne[] = "Borland International";

   char strTwo[] = "nation";

   char *ptr;

   ptr = strstr(strOne, strTwo);

   std::cout << ptr << '\n';

   return 0;

}

//输出结果为”national”。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

/*

BM算法改进的算法:Sunday Algorithm

   BM算法优于KMP

   SUNDAY

   算法描述:字符串查找算法中,最著名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-

Moore)。两个算法在最坏情 况下均具有线性的查找时间。但是在实用上,KMP算法并不比最简单的c库函数strstr()快多少,而BM算法则往往比KMP算法快上3-5倍。但是BM算法还不是最快的算法,这里介绍一种比BM算法更快一些的查找算法。例如我们要在”substring searching algorithm”查找”search”,刚开始时,把子串与文本左边对齐:

   substring searching algorithm search

   结果在第二个字符处发现不匹配,于是要把子串往后移动。但是该移动多少呢? 这就是各种算法各显神通的地方了,最简单的做法是移动一个字符位置;KMP是利用已经匹配部分的信息来移动;BM算法是做反向比较,并根据已经匹配的部分来确定移动量。这里要介绍的方法是看紧跟在当前子串之后的那个字符(第一个字符串中的’i’)。显然,不管移动多少,这个字符是肯定要参加下一步的比较的,也就是说,如果下一步匹配到了,这个字符必须在子串内。所以,可以移动子串,使子串中的最右边的这个字符与它对齐。现在子串’search’中并不存在’i’,则说明可以直接跳过一大片,从’i’之后的那个字符开始作下一步的比较,如下:

   substring searching algorithm search

   比较的结果,第一个字符就不匹配,再看子串后面的那个字符,是’r’,它在子串中出现在倒数第三位,于是把子串向后移动三位,使两个’r’对齐,如下:

   substring searching algorithm search

   这次匹配成功了!回顾整个过程,我们只移动了两次子串就找到了匹配位置, 是不是很神啊?!可以证明,用这个算法,每一步的移动量都比BM算法要大,所以肯定比BM算法更快。*/

void SUNDAY(char *text, char *patt)

{

   size_t temp[256];

   size_t *shift = temp;

   size_t i, patt_size = strlen(patt), text_size = strlen(text);

   cout << "size : " << patt_size << endl;

   for(i = 0; i < 256; i++)

  {

       *(shift+i) = patt_size + 1;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

Page 24: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

AC自动机

  }

   for(i = 0; i < patt_size; i++)

  {

       *(shift + (unsigned char)(*(patt+i))) = patt_size-i;    

       // shift['s']=6步,shitf['e']=5以此类推   }

   size_t limit = text_size - patt_size + 1;

   for(i = 0; i < limit; i += shift[text[i + patt_size]])

  {

       if(text[i] == *patt)

      {

           char *match_text = text + i + 1;

           size_t match_size = 1;

           do  // 输出所有匹配的位置           {

               if(match_size == patt_size)

              {

                   cout << "the NO. is " << i << endl;

              }

          }

           while((*match_text++) == patt[match_size++]);

      }

  }

   cout << endl;

}

int main(void)

{

   char text[100] = "substring searching algorithm search";

   char patt[10] = "search";

   SUNDAY(text, patt);

   return 0;

}

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

//求目标串中出现了几个模式串#include<bits/stdc++.h>

using namespace std;

const int  maxn = 5e5 + 10;

struct Trie {

int nxt[maxn][26], fail[maxn], end[maxn];

int root, tot;

inline int newnode()

{

for (int i = 0; i < 26; ++i)

{

nxt[tot][i] = -1;

}

fail[tot] = -1;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

Page 25: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

end[tot] = 0;

return tot++;

}

inline void Init()

{

tot = 0;

root = newnode();

}

inline void Insert(char buf[])

{

int len = strlen(buf);

int now = root;

for (int i = 0; i < len; ++i)

{

if (nxt[now][buf[i] - 'a'] == -1)

{

nxt[now][buf[i] - 'a'] = newnode();

}

now = nxt[now][buf[i] - 'a'];

}

end[now]++;

}

inline void Build()

{

queue<int>q;

q.push(root);

while (!q.empty())

{

int now = q.front();

q.pop();

for (int i = 0; i < 26; ++i)

{

if (~nxt[now][i])

{

if (now == root) fail[nxt[now][i]] = root;

else fail[nxt[now][i]] = nxt[fail[now]][i];

q.push(nxt[now][i]);

}

else

{

if (now == root) nxt[now][i] = root;

else nxt[now][i] = nxt[fail[now]][i];

}

}

}

}

inline int debug(char buf[])

{

int len = strlen(buf);

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

Page 26: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

int now = root;

int res = 0;

for (int i = 0; i < len; ++i)

{

if (nxt[now][buf[i] - 'a'] == -1) return -1;

now = nxt[now][buf[i] - 'a'];

}

res += end[now];

return res;

}

inline int query(char buf[])

{

int len = strlen(buf);

int now = root;

int cnt = 0;

for (int i = 0; i < len; ++i)

{

now = nxt[now][buf[i] - 'a'];

for (int tmp = now; tmp != root && end[tmp] != -1; tmp = fail[tmp])

{

cnt += end[tmp];

end[tmp] = -1;

}

}

return cnt;

}

}ACcount;

int n;

char str[1000000 + 10];

inline void RUN()

{

int t;

scanf("%d", &t);

while (t--)

{

scanf("%d", &n);

ACcount.Init();

for (int i = 0; i < n; ++i)

{

scanf("%s", str);

ACcount.Insert(str);

}

ACcount.Build();

scanf("%s", str);

int ans = ACcount.query(str);

printf("%d\n", ans);

}

}

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

Page 27: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

字符串Hash

/*

* 字符串 Hash

* 注意:mod选择足够大的质数(至少大于字符串个数) */

unsigned int hashA(char *url, int mod)

{

   unsigned int n = 0;

   char *b = (char *)&n;

   for (int i = 0; url[i]; i++)

  {

       b[i % 4] ^= url[i];

  }

   return n % mod;

}

unsigned int hashB(char *url, int mod)

{

   unsigned int h = 0;

   unsigned int g;

   while (*url)

  {

       h = (h << 4) + *url++;

       g = h & 0xF0000000;

       if (g)

      {

           h ^= (g >> 24);

      }

       h &= ~g;

  }

   return h % mod;

}

unsigned int hashC(char *p, int prime = 25013)

{

   unsigned int h = 0;

   unsigned int g;

   for (; *p; p++)

  {

       h = (h << 4) + *p;

       g = h & 0xF0000000;

       if (g)

      {

           h ^= (g >> 24);

           h ^= g;

      }

  }

   return h % prime;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

Page 28: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

回文树

#include<bits/stdc++.h>

using namespace std;

const int N=2e5+5;

typedef long long ll;

char s[N];

int S[N],len[N],fail[N],ch[N][26],tot,n;

ll cnt[N];

int new_node(int x)

{

   len[tot]=x,cnt[tot]=0;

   memset(ch[tot],0,sizeof(ch[tot]));

   return tot++;

}

int get_fail(int x)

{

   while(S[n-len[x]-1]!=S[n]) x=fail[x];

   return x;

}

void add(char *s)

{

   tot=0,new_node(0),new_node(-1);

   fail[0]=1,fail[1]=1,S[0]=-1,n=0;

   int last=0;

   for(int i=0;s[i];i++)

  {

       int c=s[i]-'a';

       S[++n]=c;

       int cur=get_fail(last);

       if(!ch[cur][c])

      {

           int now=new_node(len[cur]+2);

           fail[now]=ch[get_fail(fail[cur])][c];

           ch[cur][c]=now;

      }

       last=ch[cur][c];

       cnt[last]++;

  }

}

ll query(char *s)

{

   S[0]=-1,n=0;

   int last=0;ll res=0;

   for(int i=0;s[i];i++)

  {

       int c=s[i]-'a';

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

Page 29: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

后缀自动机

       S[++n]=c;

       int cur=last;

       while(cur!=1&&(!ch[cur][c]||S[n-len[cur]-1]!=S[n]))

             cur=fail[cur];

       last=ch[cur][c];

       res+=cnt[last];

  }

   return res;

}

void solve(int cas)

{

   scanf("%s",s);

   add(s);

   for(int i=tot-1;i>=0;i--) cnt[fail[i]]+=cnt[i];

   cnt[0]=cnt[1]=0;

   for(int i=2;i<=tot-1;i++) cnt[i]+=cnt[fail[i]];

   scanf("%s",s);

   ll ans=query(s);

   printf("Case #%d: %lld\n",cas,ans);

}

int main()

{

   //freopen("G.in","r",stdin);

   int T,cas=0;

   scanf("%d",&T);

   while(T--)

       solve(++cas);

   return 0;

}

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

//求有多少不同子串,以及子串出现次数#include <bits/stdc++.h>

using namespace std;

#define ll long long

#define N 200010

char s[N];

struct SAM {

int p, q, np, nq, cnt, lst, a[N][26], l[N], f[N], tot;

int Tr(char c) { return c - 'A'; }

int val(int c) { return l[c] - l[f[c]]; }

SAM() { cnt = 0; lst = ++cnt; }

void Initialize() {

memset(l, 0, sizeof(int)*(cnt + 1));

memset(f, 0, sizeof(int)*(cnt + 1));

for (int i = 0; i <= cnt; i++)for (int j = 0; j<26; j++)a[i][j] = 0;

cnt = 0; lst = ++cnt;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

Page 30: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

}

void extend(int c) {

p = lst; np = lst = ++cnt; l[np] = l[p] + 1;

while (!a[p][c] && p)a[p][c] = np, p = f[p];

if (!p) { f[np] = 1; }

else {

q = a[p][c];

if (l[p] + 1 == l[q])f[np] = q;

else {

nq = ++cnt; l[nq] = l[p] + 1;

memcpy(a[nq], a[q], sizeof(a[q]));

f[nq] = f[q]; f[np] = f[q] = nq;

while (a[p][c] == q)a[p][c] = nq, p = f[p];

}

}

}

int b[N], x[N], r[N];

void build() {

int len = strlen(s + 1);

for (int i = 1; i <= len; i++)extend(Tr(s[i]));

memset(r, 0, sizeof(int)*(cnt + 1));

memset(b, 0, sizeof(int)*(cnt + 1));

for (int i = 1; i <= cnt; i++)b[l[i]]++;

for (int i = 1; i <= len; i++)b[i] += b[i - 1];

for (int i = 1; i <= cnt; i++)x[b[l[i]]--] = i;

for (int i = p = 1; i <= len; i++) { p = a[p][Tr(s[i])]; r[p]++; }

for (int i = cnt; i; i--)r[f[x[i]]] += r[x[i]];

}

void solve() {

ll ans = 0;

int A, B;

build();

scanf("%d %d", &A, &B);

// cnt 为不同子串个数   r[x[i]] 为第i个不同子串 出现的次数

// 此处求 有多少子串出现次数在 [A, B] 之间 for (int i = 1; i <= cnt; i++)if (r[x[i]] >= A && r[x[i]] <= B) ans +=

val(x[i]);

printf("%lld\n", ans);

}

}sam;

inline void Run()

{

while (scanf("%s", s + 1) != EOF)

{

sam.Initialize();

sam.solve();

}

}

//求字典序第k大的子串#include <bits/stdc++.h>

using namespace std;

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

Page 31: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

const int N=250005;

struct State

{

   State *pre,*go[26];

   int step,v;

   void clear()

  {

       v=0;

       pre=0;

       step=0;

       memset(go,0,sizeof(go));

  }

}*root,*last;

State statePool[N*2],*b[2*N],*cur;

void init()

{

   cur=statePool;

   root=last=cur++;

   root->clear();

}

void Insert(int w)

{

   State *p=last;

   State *np=cur++;

   np->clear();

   np->step=p->step+1;

   while(p&&!p->go[w])

       p->go[w]=np,p=p->pre;

   if(p==0)

       np->pre=root;

   else

  {

       State *q=p->go[w];

       if(p->step+1==q->step)

           np->pre=q;

       else

      {

           State *nq=cur++;

           nq->clear();

           memcpy(nq->go,q->go,sizeof(q->go));

           nq->step=p->step+1;

           nq->pre=q->pre;

           q->pre=nq;

           np->pre=nq;

           while(p&&p->go[w]==q)

               p->go[w]=nq, p=p->pre;

      }

  }

   last=np;

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

Page 32: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

}

char str[N];

int son[2*N][26];

char ch[2*N][26];

int cnt[2*N],c[2*N];

void Solve(int k)

{

   int ct=0;

   int now=0;

   while(k)

  {

       for(int i=0; i<c[now]; i++)

      {

           State *tmp=statePool+son[now][i];

           if(k>tmp->v)

               k-=tmp->v;

           else

          {

               str[ct++]=ch[now][i];

               now=son[now][i];

               k--;

               break;

          }

      }

  }

   str[ct]=0;

   puts(str);

}

int main()

{

   int n;

   scanf("%s",str);

   n=strlen(str);

   init();

   for(int i=0; i<n; i++)

       Insert(str[i]-'a');

   memset(cnt,0,sizeof(cnt));

   memset(c,0,sizeof(c));

   for(State *p=statePool; p!=cur; p++)

       cnt[p->step]++;

   for(int i=1; i<cur-statePool; i++)

       cnt[i]+=cnt[i-1];

   for(State *p=statePool; p!=cur; p++)

       b[--cnt[p->step]]=p;

   for(State *p=statePool; p!=cur; p++)

       p->v=1;

   int num=cur-statePool;

   for(int i=num-1; i>=0; i--)

  {

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

Page 33: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

数论 GCD

       State *p=b[i];

       for(int j=0; j<26; j++)

      {

           if(p->go[j])

          {

               int x=p-statePool;

               int y=p->go[j]-statePool;

               son[x][c[x]]=y;

               ch[x][c[x]++]=j+'a';

               p->v+=p->go[j]->v;

          }

      }

  }

   int Q,k;

   scanf("%d",&Q);

   while(Q--)

  {

       scanf("%d",&k);   //第k大        Solve(k);

  }

   return 0;

}

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

//GCD

int gcd(int x,int y)

{

int r;

while(1)

{

r=x%y;

if(!r) break;

x=y;

y=r;

}

return y;

}

int gcd(int x, int y)

{

int r = a % b;

if (r == 0)

return b;

else

return gcd(b, r);

}

int gcd(int a, int b)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

Page 34: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

线性方程组(高斯消元)

{

return b ? gcd(b, a % b) : a;

}

//扩展GCD

//求x,y使得gcd(a, b) = a * x + b * y;

int extgcd(int a, int b, int &x, int &y)

{

   if (b == 0)

  {

       x = 1;

       y = 0;

       return a;

  }

   int d = extgcd(b, a % b, x, y);

   int t = x;

   x = y;

   y = t - a / b * y;

   return d;

}

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

//列主元/*

* 列主元gauss消去求解a[][] * x[] = b[]

* 返回是否有唯一解,若有解在b[]中 */

#define fabs(x) ((x) > 0 ? (x) : (-x))

#define eps 1e-10

const int MAXN = 100;

int gaussCpivot(int n, double a[][MAXN], double b[])

{

   int i, j, k, row = 0;

   double MAXP, temp;

   for (k = 0; k < n; k++)

  {

       for (MAXP = 0, i = k; i < n; i++)

      {

           if (fabs(a[i][k]) > fabs(MAXP))

          {

               MAXP = a[row = i][k];

          }

      }

       if (fabs(MAXP) < eps)

      {

           return 0;

      }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

Page 35: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       if (row != k)

      {

           for (j = k; j < n; j++)

          {

               temp = a[k][j];

               a[k][j] = a[row][j];

               a[row][j] = temp;

               temp = b[k];

               b[k] = b[row];

               b[row] = temp;

          }

      }

       for (j = k + 1; j < n; j++)

      {

           a[k][j] /= MAXP;

           for (i = k + 1; i < n; i++)

          {

               a[i][j] -= a[i][k] * a[k][j];

          }

      }

       b[k] /= MAXP;

       for (i = n - 1; i >= 0; i--)

      {

           for (j = i + 1; j < n; j++)

          {

               b[i] -= a[i][j] * b[j];

          }

      }

  }

   return 1;

}

//全主元/*

* 全主元gauss消去解a[][] * x[] = b[]

* 返回是否有唯一解,若有解在b[]中 */

#define fabs(x) ((x) > 0 ? (x) : (-x))

#define eps 1e-10

const int MAXN = 100;

int gaussTpivot(int n, double a[][MAXN], double b[])

{

   int i, j, k, row = 0, col = 0, index[MAXN];

   double MAXP, temp;

   for (i = 0; i < n; i++)

  {

       index[i] = i;

  }

   for (k = 0; k < n; k++)

  {

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

Page 36: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       for (MAXP = 0, i = k; i < n; i++)

      {

           for (j = k; j < n; j++)

          {

               if (fabs(a[i][j] > fabs(MAXP)))

              {

                   MAXP = a[row = i][col = j];

              }

          }

      }

       if (fabs(MAXP) < eps)

      {

           return 0;

      }

       if (col != k)

      {

           for (i = 0; i < n; i++)

          {

               temp = a[i][col];

               a[i][col] = a[i][k];

               a[i][k] = temp;

          }

           j = index[col];

           index[col] = index[k];

           index[k] = j;

      }

       if (row != k)

      {

           for (j = k; j < n; j++)

          {

               temp = a[k][j];

               a[k][j] = a[row][j];

               a[row][j] = temp;

          }

           temp = b[k];

           b[k] = b[row];

           b[row] = temp;

      }

       for (j = k + 1; j < n; j++)

      {

           a[k][j] /= MAXP;

           for (i = k + 1; i < n; i++)

          {

               a[i][j] -= a[i][k] * a[k][j];

          }

      }

       b[k] /= MAXP;

       for (i = k + 1; i < n; i++)

      {

           b[i] -= b[k] * a[i][k];

      }

  }

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

Page 37: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

模线性方程(组)

   for (i = n - 1; i >= 0; i--)

  {

       for (j = i + 1; j < n; j++)

      {

           b[i] -= a[i][j] * b[j];

      }

  }

   for (k = 0; k < n; k++)

  {

       a[0][index[k]] = b[k];

  }

   for (k = 0; k < n; k++)

  {

       b[k] = a[0][k];

  }

   return 1;

}

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

//公共部分(扩展GCD)int extgcd(int a, int b, int &x, int &y)

{

   if (b == 0)

  {

       x = 1;

       y = 0;

       return a;

  }

   int d = extgcd(b, a % b, x, y);

   int t = x;

   x = y;

   y = t - a / b * y;

   return d;

}

//模线性方程//模线性方程 a * x = b (% n)

void modeq(int a, int b, int n)

{

   int e, i, d, x, y;

   d = extgcd(b, a % b, x, y);

   if (b % d > 0)

  {

       cout << "No answer!\n";

  }

   else

  {

       e = (x * (b / d)) % n;

       for (i = 0; i < d; i++)

      {

           cout << i + 1 << "-th ans:" << (e + i * (n / d)) % n << '\n';

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

Page 38: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

      }

  }

   return ;

}

//模线性方程组(互质)/*

* 模线性方程组 * a = B[1](% W[1]); a = B[2](% W[2]); ... a = B[k](% W[k]);

* 其中W,B已知,W[i] > 0且W[i]与W[j]互质,求a(中国剩余定理) */

int china(int b[], int w[], int k)

{

   int i, d, x, y, m, a = 0, n = 1;

   for (i = 0; i < k; i++)

  {

       n *= w[i];  // 注意不能overflow

  }

   for (i = 0; i < k; i++)

  {

       m = n / w[i];

       d = extgcd(w[i], m, x, y);

       a = (a + y * m * b[i]) % n;

  }

   if (a > 0)

  {

       return a;

  }

   else

  {

       return (a + n);

  }

}

//模线性方程组(不要求互质)typedef long long ll;

const int MAXN = 11;

int n, m;

int a[MAXN], b[MAXN];

int main(int argc, const char * argv[])

{

   int T;

   cin >> T;

   while (T--)

  {

       cin >> n >> m;

       for (int i = 0; i < m; i++)

      {

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

Page 39: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

素数相关

           cin >> a[i];

      }

       for (int i = 0; i < m; i++)

      {

           cin >> b[i];

      }

       ll ax = a[0], bx = b[0], x, y;

       int flag = 0;

       for (int i = 1; i < m; i++)

      {

           ll d = extgcd(ax, a[i], x, y);

           if ((b[i] - bx) % d != 0)

          {

               flag = 1;   // 无整数解                break;

          }

           ll tmp = a[i] / d;

           x = x * (b[i] - bx) / d;    // 约分            x = (x % tmp + tmp) % tmp;

           bx = bx + ax * x;

           ax = ax * tmp;              // ax = ax * a[i] / d

      }

       if (flag == 1 || n < bx)

      {

           puts("0");

      }

       else

      {

           ll ans = (n - bx) / ax + 1;

           if (bx == 0)

          {

               ans--;

          }

           printf("%lld\n", ans);

      }

  }

   return 0;

}

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

/*

* 素数筛选,判断小于MAXN的数是不是素数 * notprime是一张表,false表示是素数,true表示不是 */

const int MAXN = 1000010;

bool notprime[MAXN];

1

2

3

4

5

6

7

8

Page 40: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

void init()

{

   memset(notprime, false, sizeof(notprime));

   notprime[0] = notprime[1] = true;

   for (int i = 2; i < MAXN; i++)

  {

       if (!notprime[i])

      {

           if (i > MAXN / i)   // 阻止后边i * i溢出(或者i,j用long long)

          {

               continue;

          }

           // 直接从i * i开始就可以,小于i倍的已经筛选过了            for (int j = i * i; j < MAXN; j += i)

          {

               notprime[j] = true;

          }

      }

  }

}

/*

* 素数筛选,查找出小于等于MAXN的素数 * prime[0]存素数的个数 */

const int MAXN = 100000;

int prime[MAXN + 1];

void getPrime()

{

   memset(prime, 0, sizeof(prime));

   for (int i = 2; i <= MAXN; i++)

  {

       if (!prime[i])

      {

           prime[++prime[0]] = i;

      }

       for (int j = 1; j <= prime[0] && prime[j] <= MAXN / i; j++)

      {

           prime[prime[j] * i] = 1;

           if (i % prime[j] == 0)

          {

               break;

          }

      }

  }

}

//线性筛法

#include<iostream>

using namespace std;    

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

Page 41: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

const long N = 200000;  

long prime[N] = {0},num_prime = 0;    

int isNotPrime[N] = {1, 1};  

int main()    

{    

    for(long i = 2 ; i < N ; i ++)      

      {            

if(! isNotPrime[i])              

prime[num_prime ++]=i;  

//关键处1        

for(long j = 0 ; j < num_prime && i * prime[j] <  N ; j ++)

  {              

    isNotPrime[i * prime[j]] = 1;  

if( !(i % prime[j] ) )  //关键处2                  

break;          

}        

}        

return 0;  

}  

/*

* 随机素数测试(伪素数原理) * CALL: bool res = miller(n);

* 快速测试n是否满足素数的“必要”条件,出错概率极低 * 对于任意奇数n > 2和正整数s,算法出错概率≤2^(-s)

*/

int witness(int a, int n)

{

   int x, d = 1;

   int i = ceil(log(n - 1.0) / log(2.0)) - 1;

   for (; i >= 0; i--)

  {

       x = d;

       d = (d * d) % n;

       if (d == 1 && x != 1 && x != n - 1)

      {

           return 1;

      }

       if (((n - 1) & (1 << i)) > 0)

      {

           d = (d * a) % n;

      }

  }

   return (d == 1 ? 0 : 1);

}

int miller(int n, int s = 50)

{

   if (n == 2)     // 质数返回1

  {

       return 1;

  }

   if (n % 2 == 0) // 偶数返回0

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

Page 42: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

  {

       return 0;

  }

   int j, a;

   for (j = 0; j < a; j++)

  {

       a = rand() * (n - 2) / RAND_MAX + 1;

       // rand()只能随机产生[0, RAND_MAX)内的整数        // 而且这个RAND_MAX只有32768直接%n的话是永远        // 也产生不了[RAND_MAX, n)之间的数        if (witness(a, n))

      {

           return 0;

      }

  }

   return 1;

}

//大数素数测试#define MAXL 4

#define M10 1000000000

#define Z10 9

const int zero[MAXL - 1] = {0};

struct bnum

{

   int data[MAXL]; // 断成每截9个长度

   // 读取字符串并转存    void read()

  {

       memset(data, 0, sizeof(data));

       char buf[32];

       scanf("%s", buf);

       int len = (int)strlen(buf);

       int i = 0, k;

       while (len >= Z10)

      {

           for (k = len - Z10; k < len; ++k)

          {

               data[i] = data[i] * 10 + buf[k] - '0';

          }

           ++i;

           len -= Z10;

      }

       if (len > 0)

      {

           for (k = 0; k < len; ++k)

          {

               data[i] = data[i] * 10 + buf[k] - '0';

          }

      }

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

Page 43: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

  }

   bool operator == (const bnum &x)

  {

       return memcmp(data, x.data, sizeof(data)) == 0;

  }

   bnum & operator = (const int x)

  {

       memset(data, 0, sizeof(data));

       data[0] = x;

       return *this;

  }

   bnum operator + (const bnum &x)

  {

       int i, carry = 0;

       bnum ans;

       for (i = 0; i < MAXL; ++i)

      {

           ans.data[i] = data[i] + x.data[i] + carry;

           carry = ans.data[i] / M10;

           ans.data[i] %= M10;

      }

       return  ans;

  }

   bnum operator - (const bnum &x)

  {

       int i, carry = 0;

       bnum ans;

       for (i = 0; i < MAXL; ++i)

      {

           ans.data[i] = data[i] - x.data[i] - carry;

           if (ans.data[i] < 0)

          {

               ans.data[i] += M10;

               carry = 1;

          }

           else

          {

               carry = 0;

          }

      }

       return ans;

  }

   // assume *this < x * 2

   bnum operator % (const bnum &x)

  {

       int i;

       for (i = MAXL - 1; i >= 0; --i)

      {

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

Page 44: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

           if (data[i] < x.data[i])

          {

               return *this;

          }

           else if (data[i] > x.data[i])

          {

               break;

          }

      }

       return ((*this) - x);

  }

   bnum & div2()

  {

       int  i, carry = 0, tmp;

       for (i = MAXL - 1; i >= 0; --i)

      {

           tmp = data[i] & 1;

           data[i] = (data[i] + carry) >> 1;

           carry = tmp * M10;

      }

       return *this;

  }

   bool is_odd()

  {

       return (data[0] & 1) == 1;

  }

   bool is_zero()

  {

       for (int i = 0; i < MAXL; ++i)

      {

           if (data[i])

          {

               return false;

          }

      }

       return true;

  }

};

void mulmod(bnum &a0, bnum &b0, bnum &p, bnum &ans)

{

   bnum tmp = a0, b = b0;

   ans = 0;

   while (!b.is_zero())

  {

       if (b.is_odd())

      {

           ans = (ans + tmp) % p;

      }

       tmp = (tmp + tmp) % p;

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

Page 45: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       b.div2();

  }

}

void powmod(bnum &a0, bnum &b0, bnum &p, bnum &ans)

{

   bnum tmp = a0, b = b0;

   ans = 1;

   while (!b.is_zero())

  {

       if (b.is_odd())

      {

           mulmod(ans, tmp, p, ans);

      }

       mulmod(tmp, tmp, p, tmp);

       b.div2();

  }

}

bool MillerRabinTest(bnum &p, int iter)

{

   int i, small = 0, j, d = 0;

   for (i = 1; i < MAXL; ++i)

  {

       if (p.data[i])

      {

           break;

      }

  }

   if (i == MAXL)

  {

       // small integer test

       if (p.data[0] < 2)

      {

           return  false;

      }

       if (p.data[0] == 2)

      {

           return  true;

      }

       small = 1;

  }

   if (!p.is_odd())

  {

       return false;   // even number

  }

   bnum a, s, m, one, pd1;

   one = 1;

   s = pd1 = p - one;

   while (!s.is_odd())

  {

       s.div2();

       ++d;

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

Page 46: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

合数相关

  }

   for (i = 0; i < iter; ++i)

  {

       a = rand();

       if (small)

      {

           a.data[0] = a.data[0] % (p.data[0] - 1) + 1;

      }

       else

      {

           a.data[1] = a.data[0] / M10;

           a.data[0] %= M10;

      }

       if (a == one)

      {

           continue;

      }

       powmod(a, s, p, m);

       for (j = 0; j < d && !(m == one) && !(m == pd1); ++j)

      {

           mulmod(m, m, p, m);

      }

       if (!(m == pd1) && j > 0)

      {

           return false;

      }

  }

   return true;

}

int main()

{

   bnum x;

   x.read();

   puts(MillerRabinTest(x, 5) ? "Yes" : "No");

   return 0;

}

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

/*

* 合数的分解需要先进行素数的筛选 * factor[i][0]存放分解的素数 * factor[i][1]存放对应素数出现的次数 * fatCnt存放合数分解出的素数个数(相同的素数只算一次)

*/

const int MAXN = 10000;

1

2

3

4

5

6

7

8

Page 47: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

int prime[MAXN + 1];

// 获取素数void getPrime()

{

   memset(prime, 0, sizeof(prime));

   for (int i = 2; i <= MAXN; i++)

  {

       if (!prime[i])

      {

           prime[++prime[0]] = i;

      }

       for (int j = 1; j <= prime[0] && prime[j] <= MAXN / i; j++)

      {

           prime[prime[j] * i] = 1;

           if (i % prime[j] == 0)

          {

               break;

          }

      }

  }

   return ;

}

long long factor[100][2];

int fatCnt;

// 合数分解int getFactors(long long x)

{

   fatCnt = 0;

   long long tmp = x;

   for (int i = 1; prime[i] <= tmp / prime[i]; i++)

  {

       factor[fatCnt][1] = 0;

       if (tmp % prime[i] == 0)

      {

           factor[fatCnt][0] = prime[i];

           while (tmp % prime[i] == 0)

          {

               factor[fatCnt][1]++;

               tmp /= prime[i];

          }

           fatCnt++;

      }

  }

   if (tmp != 1)

  {

       factor[fatCnt][0] = tmp;

       factor[fatCnt++][1] = 1;

  }

   return fatCnt;

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

Page 48: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

}

//分解质因数

//将一个数n分解为若干个从小到大排列的质数的积#include <iostream>

using namespace std;

int main()

{

   int n, n2;

   cin >> n;  

   cout << n << "=";

   n2 = n;

   if(n<2)return 0;                //小于2的数不合法,若n为质数则输出它本身    for(int i = 2;i*i<=n2;i++)        //根号n复杂度   {        

       while(n2%i==0)

      {

           n2=n2/i;

           cout << i ;

           if(n2!=1)cout << "*";

      }

  }

   if(n2!=1)    cout << n2;        //当n为质数    return 0;

}

//求因子个数

inline void work()

{

int res = 0;

for (int i = 1; i * i <= n; ++i)

{

if (n % i == 0)

{

++res;

if (n / i != i) ++res;

}

}

printf("%d\n", res);

}

//得到因子个数

inline void work()

{

int res = 1; --p;  

for (int i = 2; i * i <= p; ++i)

{

int tmp = 0;

while (p % i == 0)

{

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

Page 49: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

组合数学相关

p = p / i;

++tmp;

}

res *= (tmp + 1);

}

if (p != 1) res *= 2;

printf("%d\n", res);

}

115

116

117

118

119

120

121

122

/*

定理One

{1, 2, … n}的r组合a1, a2, … ar出现在所有r组合中的字典序位置编号, C(n, m)表示n中取m的组合数index = C(n, r) - C(n - a1, r) - C(n - a2, r - 1) - … - C(n - ar, 1)

Two

k * C(n, k) = n * C(n - 1, k - 1);

C(n, 0) + C(n, 2) + … = C(n, 1) + C(n, 3) + …

1 * C(n, 1) + 2 * C(n, 2) + … + n * C(n, n) = n * 2^(n - 1)

Three · Catalan数

C_n = C(2 * n, n) / (n + 1)

C_n = (4 * n - 2) / (n + 1) * C_n - 1

C_1 = 1

Four · Stirling数 · 1

s(p, k)是将p个物体排成k个非空的循环排列的方法数(或者: 把p个人排成k个非空圆圈的方法数)。s(p, k) = (p - 1) * s(p - 1, k) + s(p - 1, k - 1);

Five · Stirling数 · 2

S(p, k) = k * S(p - 1, k) + S(p - 1, k - 1).

S(p, 0) = 0, (p >= 1);

S(p, p) = 1, (p >= 0);

且有 S(p, 1) = 1, (p >= 1);

S(p, 2) = 2^(p - 1) - 1, (p >= 2);

S(p, p - 1) = C(p, 2);

Six · Bell数

B_p = S(p, 0) + S(p, 1) + … + S(p, p)

B_p = C(p - 1, 0) * B_0 + C(p - 1, 1) * B_1 + … + C(p - 1, p - 1) * B_(p - 1)

*/

//组合数C(n, r)

int com(int n, int r)   // return C(n, r)

{

   if (n - r > r)

  {

       r = n - r;      // C(n, r) = C(n, n - r)

  }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

Page 50: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

   int i, j, s = 1;

   for (i = 0, j = 1; i < r; ++i)

  {

       s *= (n - i);

       for (; j <= r && s % j == 0; ++j)

      {

           s /= j;

      }

  }

   return s;

}

//组合数C(a, b) (预处理)

typedef long long ll;

const ll MOD = 1e9 + 7;     // 必须为质数才管用const ll MAXN = 1e5 + 3;

ll fac[MAXN];       // 阶乘ll inv[MAXN];       // 阶乘的逆元

ll QPow(ll x, ll n)

{

   ll ret = 1;

   ll tmp = x % MOD;

   while (n)

  {

       if (n & 1)

      {

           ret = (ret * tmp) % MOD;

      }

       tmp = tmp * tmp % MOD;

       n >>= 1;

  }

   return ret;

}

void init()

{

   fac[0] = 1;

   for (int i = 1; i < MAXN; i++)

  {

       fac[i] = fac[i - 1] * i % MOD;

  }

   inv[MAXN - 1] = QPow(fac[MAXN - 1], MOD - 2);

   for (int i = MAXN - 2; i >= 0; i--)

  {

       inv[i] = inv[i + 1] * (i + 1) % MOD;

  }

}

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

Page 51: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

ll C(ll a, ll b)

{

   if (b > a)

  {

       return 0;

  }

   if (b == 0)

  {

       return 1;

  }

   return fac[a] * inv[b] % MOD * inv[a - b] % MOD;

}

//集合划分问题

/*

* n元集合分划为k类的方案数记为S(n, k),称为第二类Stirling数。 * 如{A,B,C}可以划分{{A}, {B}, {C}}, {{A, B}, {C}}, {{B, C}, {A}}, {{A, C}, {B}},

{{A, B, C}}。 * 即一个集合可以划分为不同集合(1...n个)的种类数 * CALL: compute(N); 每当输入一个n,输出B[n]

*/

const int N = 2001;

int data[N][N], B[N];

void NGetM(int m, int n)    // m 个数 n 个集合{

   // data[i][j]: i个数分成j个集合    int min, i, j;

   data[0][0] = 1;

   for (i = 1; i <= m; i++)

  {

       data[i][0] = 0;

  }

   for (i = 0; i <= m; i++)

  {

       data[i][i + 1] = 0;

  }

   for (i = 1; i <= m; i++)

  {

       if (i < n)

      {

           min = i;

      }

       else

      {

           min = n;

      }

       for (j = 1; j <= min; j++)

      {

               data[i][j] = (j * data[i - 1][j] + data[i - 1][j - 1]);

      }

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

Page 52: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

  }

   return ;

}

void compute(int m)

{

   // b[i]: Bell数    NGetM(m, m);

   memset(B, 0, sizeof(B));

   int i, j;

   for (i=1; i <= m; i++)

  {

       for (j = 0; j <= i; j++)

      {

           B[i] += data[i][j];

      }

  }

   return ;

}

//卢卡斯定理(从(1, 1)到(n, m)的走法,机器人走方格问题)

#define MOD 1000000007

typedef long long LL;

LL quickPower(LL a, LL b)

{

   LL ans = 1;

   a %= MOD;

   while (b)

  {

       if (b & 1)

      {

           ans = ans * a % MOD;

      }

       b >>= 1;

       a = a * a % MOD;

  }

   return ans;

}

LL c(LL n, LL m)

{

   if (m > n)

  {

       return 0;

  }

   LL ans = 1;

   for (int i = 1; i <= m; i++)

  {

       LL a = (n + i - m) % MOD;

       LL b = i % MOD;

       ans = ans * (a * quickPower(b, MOD - 2) % MOD) % MOD;

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

Page 53: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

Polya计数

  }

   return ans;

}

LL lucas(LL n, LL m)

{

   if (m == 0)

  {

       return 1;

  }

   return c(n % MOD, m % MOD) * lucas(n / MOD, m / MOD) % MOD;

}

int main(int argc, const char * argv[])

{

   LL n, m;

   while (~scanf("%lld %lld", &n, &m))

  {

       LL max, min;

       max = n + m - 3;

       min = m - 1;

       printf("%lld\n", lucas(max - 1, min - 1));

  }

   return 0;

}

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

/*

* c种颜色的珠子,组成长为s的项链,项链没有方向和起始位置 */

int gcd(int a, int b)

{

   return b ? gcd(b, a % b) : a;

}

int main(int argc, const char * argv[])

{

   int c, s;

   while (cin >> c >> s)

  {

       int k;

       long long p[64];

       p[0] = 1;                   // power of c

       for (k = 0; k < s; k++)

      {

           p[k + 1] = p[k] * c;

      }

       // reflection part

       long long count = s & 1 ? s * p[s / 2 + 1] : (s / 2) * (p[s / 2] + p[s / 2

+ 1]);

       // rotation part

       for (k = 1 ; k <= s ; k++)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

Page 54: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

最大1矩阵

      {

           count += p[gcd(k, s)];

           count /= 2 * s;

      }

       cout << count << '\n';

  }

   return 0;

}

25

26

27

28

29

30

31

32

const int N = 1000;

bool a[N][N];

int Run(const int &m, const int &n)     // a[1...m][1...n]

{                                       // O(m*n)

   int i, j, k, l, r, max=0;

   int col[N];

   for (j = 1; j <= n; j++)

  {

       if (a[1][j] == 0 )

      {

           col[j] = 0;

      }

       else

      {

           for (k = 2; k <= m && a[k][j] == 1; k++);

           col[j] = k - 1;

      }

  }

   for (i = 1; i <= m; i++)

  {

       if (i > 1)

      {

           for (j = 1; j <= n; j++)

          {

               if (a[i][j] == 0)

              {

                   col[j] = 0;

              }

               else

              {

                   if (a[i - 1][j] == 0)

                  {

                       for (k = i + 1; k <= m && a[k][j] == 1; k++);

                       col[j] = k-1;

                  }

              }

          }

      }

       for (j = 1; j <= n; j++)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

Page 55: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

约瑟夫环问题

      {

           if (col[j] >= i)

          {

               for (l = j - 1; l > 0 && col[l] >= col[j]; --l);

               l++;

               for (r = j + 1; r <= n && col[r] >= col[j]; ++r);

               r--;

               int res = (r - l + 1) * (col[j] - i + 1);

               if( res > max )

              {

                   max = res;

              }

          }

      }

  }

   return max;

}

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

/*

* n个人(编号 1...n),先去掉第m个数,然后从m+1个开始报1,

* 报到k的退出,剩下的人继续从1开始报数.求胜利者的编号.

*/

int main(int argc, const char * argv[])

{

   int n, k, m;

   while (cin >> n >> k >> m, n || k || m)

  {

       int i, d, s = 0;

       for (i = 2; i <= n; i++)

      {

           s = (s + k) % i;

      }

       k = k % n;

       if (k == 0)

      {

           k = n;

      }

       d = (s + 1) + (m - k);

       if (d >= 1 && d <= n)

      {

           cout << d << '\n';

      }

       else if (d < 1)

      {

           cout << n + d << '\n';

      }

       else if (d > n)

      {

           cout << d % n << '\n';

      }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

Page 56: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

博弈论

  }

   return 0;

}

//函数图像法/*

* n 个人数到 k 出列,最后剩下的人编号 */

unsigned long long n, k;

int main()

{

   cin >> n >> k;

   long long y = k % 2;

   long long x = 2, t = 0;

   long long z1 = y, z2 = x;

   while (x <= n)

  {

       z1 = y;

       z2 = x;

       t = (x - y) / (k - 1);

       if (t == 0)

      {

           t++;

      }

       y = y + t * k - ((y + t * k) / (x + t)) * (x + t);

       x += t;

  }

   cout << (z1 + (n - z2) * k) % n + 1 << endl;

   return 0;

}

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

//Bash

#define _MAX 10000

int a[_MAX];

int b[_MAX];

int bash(int N, int K)

{

   if (N % (K + 1) == 0)

  {

       return 2;

  }

   return 1;

}

int main()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

Page 57: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

{

   int T;

   scanf("%d", &T);

   for (int i = 0; i < T; i++)

  {

       scanf("%d%d", a + i, b + i);

  }

   for (int i = 0; i < T; i++)

  {

       if (bash(a[i], b[i]) == 1)

      {

           printf("A\n");

      }

       else

      {

           printf("B\n");

      }

  }

   return 0;

}

//Nim

int main(int argc, const char * argv[])

{

   int N, stone, tag = 0;

   scanf("%d", &N);

   while (N--)

  {

       scanf("%d", &stone);

       tag ^= stone;

  }

   //tag为0则为后手赢,否则为先手赢    printf("%c\n", tag == 0 ? 'B' : 'A');

   return 0;

}

//SG打表const int MAX_DIG = 64;

// SG打表// f[]:可以取走的石子个数// sg[]:0~n的SG函数值// hash[]:mex{}

int f[MAX_DIG];

int sg[MAX_DIG];

int hash[MAX_DIG];

void getSG(int n)

{

   memset(sg, 0, sizeof(sg));

   for (int i = 1; i <= n; i++)

  {

       memset(hash, 0, sizeof(hash));

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

Page 58: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       for (int j = 1; f[j] <= i; j++)

      {

           hash[sg[i - f[j]]] = 1;

      }

       for (int j = 0; j <= n; j++)    // 求mes{}中未出现的最小的非负整数       {

           if (hash[j] == 0)

          {

               sg[i] = j;

               break;

          }

      }

  }

}

//SG DFS

const int MAX_DIG = 64;

// DFS

// 注意 S数组要按从小到大排序 SG函数要初始化为-1 对于每个集合只需初始化1遍// n是集合s的大小 S[i]是定义的特殊取法规则的数组int s[MAX_DIG];

int sg[MAX_DIG * 100];

int n;

int SG_dfs(int x)

{

   if (sg[x] != -1)

  {

       return sg[x];

  }

   bool vis[MAX_DIG];

   memset(vis, 0, sizeof(vis));

   for (int i = 0; i < n; i++)

  {

       if (x >= s[i])

      {

           SG_dfs(x - s[i]);

           vis[sg[x - s[i]]] = 1;

      }

  }

   int e;

   for (int i = 0; ; i++)

  {

       if (!vis[i])

      {

           e = i;

           break;

      }

  }

   return sg[x] = e;

}

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

Page 59: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

周期性方程

//Wythoff

int main()

{

   int t, a, b, m, k;

   scanf("%d", &t);

   while (t--)

  {

       scanf("%d%d", &a, &b);

       if (a > b)

      {

           a ^= b;

           b ^= a;

           a ^= b;

      }

       m = b - a;

       k = (int)(m * (1 + sqrt(5)) / 2.0);

       //m = ? * a

       //k = m / ?

       //?:黄金分割数        //如果a == k,则为后手赢,否则先手赢(奇异局)        printf("%s\n", a == k ? "B" : "A");

  }

   return 0;

}

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

//追赶法解周期性方程/*

* 周期性方程定义(n = 5)

* |a_1 b_1 c_1 d_1 e_1| = x_1 --- 1

* |e_2 a_2 b_2 c_2 d_2| = x_2 --- 2

* |d_2 e_2 a_2 b_2 c_2| = x_3 --- 3

* |c_4 d_2 e_2 a_4 b_4| = x_4 --- 4

* |b_5 c_5 d_5 e_5 a_5| = x_5 --- 5

* 输入: a[], b[], c[], x[]

* 输出: 求解结果x在x[]中 */

const int MAXN = 1000;

int a[MAXN];

int b[MAXN];

int c[MAXN];

int x[MAXN];

void run()

{

   c[0] /= b[0];

   a[0] /= b[0];

   x[0] /= b[0];

   for (int i = 1; i < MAXN - 1; i++)

  {

       double temp = b[i] - a[i] * c[i - 1];

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

Page 60: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

阶乘

       c[i] /= temp;

       x[i] = (x[i] - a[i] * x[i - 1]) / temp;

       a[i] = -a[i] * a[i - 1] / temp;

  }

   a[MAXN - 2] = -a[MAXN - 2] - c[MAXN - 2];

   for (int i = MAXN - 3; i >= 0; i--)

  {

       a[i] = -a[i] - c[i] * a[i + 1];

       x[i] -= c[i] * x[i + 1];

  }

   x[MAXN - 1] -= (c[MAXN - 1] * x[0] + a[MAXN - 1] * x[MAXN - 2]);

   x[MAXN - 1] /= (c[MAXN - 1] * a[0] + a[MAXN - 1] * a[MAXN - 2] + b[MAXN - 1]);

   for (int i = MAXN - 2; i >= 0; i --)

  {

       x[i] += a[i] * x[MAXN - 1];

  }

   return ;

}

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

//阶乘最后非零位/*

* 阶乘最后非零位 复杂度O(nlongn)

* 返回改为,n以字符串方式传入 */

#define MAXN 10000

const int mod[20] = {1, 1, 2, 6, 4, 2, 2, 4, 2, 8, 4, 4, 8, 4, 6, 8, 8, 6, 8, 2};

int lastDigit(char *buf)

{

   int len = (int)strlen(buf);

   int a[MAXN], i, c, ret = 1;

   if (len == 1)

  {

       return mod[buf[0] - '0'];

  }

   for (i = 0; i < len; i++)

  {

       a[i] = buf[len - 1 - i] - '0';

  }

   for (; len; len -= !a[len - 1])

  {

       ret = ret * mod[a[1] % 2 * 10 + a[0]] % 5;

       for (c = 0, i = len - 1; i >= 0; i--)

      {

           c = c * 10 + a[i];

           a[i] = c / 5;

           c %= 5;

      }

  }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

Page 61: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

排列组合

   return ret + ret % 2 * 5;

}

//n的阶乘的长度#define PI 3.1415926

int main()

{

   int n, a;

   while (~scanf(“%d", &n))

  {

       a = (int)((0.5 * log(2 * PI * n) + n * log(n) - n) / log(10));

       printf("%d\n", a + 1);

  }

   return 0;

}

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

//类循环排列

//用递归实现多重循环,本递归程序相当于n重循环,每重循环的长度为m的情况,所以输出共有m^n行。/*

* 输入样例: 3 2

* 输出样例:

* 0 0 0

* 0 0 1

* 0 1 0

* 0 1 1

* 1 0 0

* 1 0 1

* 1 1 0

* 1 1 1

*/

#define MAX_N 10

int n, m;                       // 相当于n重循环,每重循环长度为m

int rcd[MAX_N];                 // 记录每个位置填的数void loop_permutation(int l)

{

   int i;

   if (l == n)                 // 相当于进入了 n 重循环的最内层   {

       for (i = 0; i < n; i++)

      {

           cout << rcd[i];

           if (i < n-1)

          {

               cout << " ";

          }

      }

       cout << "\n";

       return ;

  }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

Page 62: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

   for (i = 0; i < m; i++)     // 每重循环长度为m

  {

       rcd[l] = i;             // 在l位置放i

       loop_permutation(l + 1);  // 填下一个位置   }

}

int main()

{

   while (cin >> n >> m)

  {

       loop_permutation(0);

  }

   return 0;

}

//全排列

//dfs即可……

/*

* 对输入的n个数作全排列。

* 输入样例:

* 3

* 1 2 3

* 输出样例:

* 123

* 132

* 213

* 231

* 312

* 321

*/

#define MAX_N 10

int n;                      // 共n个数int rcd[MAX_N];             // 记录每个位置填的数int used[MAX_N];            // 标记数是否用过int num[MAX_N];             // 存放输入的n个数

void full_permutation(int l)

{

   int i;

   if (l == n)

  {

       for (i = 0; i < n; i++)

      {

           printf("%d", rcd[i]);

           if (i < n-1)

          {

               printf(" ");

          }

      }

       printf("\n");

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

Page 63: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       return ;

  }

   for (i = 0; i < n; i++)         // 枚举所有的数(n个),循环从开始        if (!used[i])

      {                           // 若num[i]没有使用过, 则标记为已使用            used[i] = 1;

           rcd[l] = num[i];        // 在l位置放上该数            full_permutation(l+1);  // 填下一个位置            used[i] = 0;            // 清标记       }

}

int read_data()

{

   int i;

   if (scanf("%d", &n) == EOF)

  {

       return 0;

  }

   for (i = 0; i < n; i++)

  {

       scanf("%d", &num[i]);

  }

   for (i = 0; i < n; i++)

  {

       used[i] = 0;

  }

   return 1;

}

int main()

{

   while (read_data())

  {

       full_permutation(0);

  }

   return 0;

}

/*

程序通过used数组,标记数是否被用过,可以产生全排列,共有n!种。但是, 通过观察会发现,若输入的n个数有重复,那么在输出的n!种排列中,必然存在重复的项,若不允许输出重复的项,该怎么做呢?

*/

//不重复排列

//DFS解法:

/*

* 输入n个数,输出由这n个数构成的排列,不允许出现重复的项。

* 输入样例:

* 3

* 1 1 2

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

Page 64: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

* 输出样例:

* 1 1 2

* 1 2 1

* 2 1 1

*/

#define MAX_N 10

int n, m;           // 共有n个数,其中互不相同的有m个int rcd[MAX_N];     // 记录每个位置填的数int used[MAX_N];    // 标记m个数可以使用的次数int num[MAX_N];     // 存放输入中互不相同的m个数

void unrepeat_permutation(int l)

{

   int i;

   if (l == n)     // 填完了n个数,则输出   {

       for (i = 0; i < n; i++)

      {

           printf("%d", rcd[i]);

           if (i < n - 1)

          {

               printf(" ");

          }

      }

       printf("\n");

       return ;

  }

   for (i = 0; i < m; i++)             // 枚举m个本质不同的数   {

       if (used[i] > 0)                // 若数num[i]还没被用完,则可使用次数减       {

           used[i]--;

           rcd[l] = num[i];            // 在l位置放上该数            unrepeat_permutation(l+1);  // 填下一个位置            used[i]++;                  // 可使用次数恢复       }

  }

}

int read_data()

{

   int i, j, val;

   if (scanf("%d", &n) == EOF)

  {

       return 0;

  }

   m = 0;

   for (i = 0; i < n; i++)

  {

       scanf("%d", &val);

       for (j = 0; j < m; j++)

      {

           if (num[j] == val)

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

Page 65: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

          {

               used[j]++; break;

          }

      }

       if (j == m)

      {

           num[m] = val;

           used[m++] = 1;

      }

  }

   return 1;

}

int main()

{

   while (read_data())

  {

       unrepeat_permutation(0);

  }

   return 0;

}

/*

本程序将全排列中的used标记数组改为记录输入中每个本质不同的数出现的次数,并在递归函数中使用。需要注意的是,在输入过程中,应剔除重复的数值。实际上,重复排列的产生是由于同一个位置被多次填入了相同的数,并且这多次填入又是在同一次循环过程中完成的。本方法通过统计每个本质不同的数的个数,使得循环长度由n变为m,这样,i一旦自增,就再也不会指向原先填入过的数了。这种方法剪去了重复项的生成,从而加快了搜索速度,是深度优先搜索中常用的剪枝技巧。*/

//规律性解法:

int main()

{

   char ch[10];

   scanf("%s",ch);

   int len = (int)strlen(ch);

   sort(ch, ch + len);

   int cnt;

   do

  {

       printf("%s\n", ch);

       cnt = -1;

       for (int i = len - 1; i > 0; i--)

      {

           if (ch[i] > ch[i - 1])

          {

               cnt = i - 1;

               for (int j = len - 1; j >= 0; j--)

              {

                   if (ch[j] > ch[cnt])

                  {

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

Page 66: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

                       char tmp = ch[j] ^ ch[cnt];

                       ch[j] ^= tmp;

                       ch[cnt] ^= tmp;

                       for (int k = i; k <= (i + len - 1) / 2; k++)    

                           // ch[cnt]和ch[j]置换后变大,后边的为递                       {                                              

                           // 减,所以需要倒置,变为递增                            tmp = ch[k] ^ ch[len - 1 + i - k];

                           ch[k] ^= tmp;

                           ch[len - 1 + i - k] ^= tmp;

                      }

                       break;

                  }

              }

               break;

          }

      }

  } while (cnt != -1);

   return 0;

}

//一般组合/*

* 输入n个数,从中选出m个数可构成集合,输出所有这样的集合。 * 输入样例:

* 4 3

* 1 2 3 4

* 输出样例:

* 1 2 3

* 1 2 4

* 1 3 4

* 2 3 4

*/

#define MAX_N 10

int n, m;       // 从n个数中选出m个构成组合int rcd[MAX_N]; // 记录每个位置填的数int num[MAX_N]; // 存放输入的n个数

void select_combination(int l, int p)

{

   int i;

   if (l == m) // 若选出了m个数, 则打印   {

       for (i = 0; i < m; i++)

      {

           printf("%d", rcd[i]);

           if (i < m - 1)

          {

               printf(" ");

          }

      }

       printf("\n");

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

Page 67: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       return ;

  }

   for (i = p; i < n; i++) // 上个位置填的是num[p-1],本次从num[p]开始试探   {

       rcd[l] = num[i];    // 在l位置放上该数        select_combination(l + 1, i + 1);   // 填下一个位置   }

}

int read_data()

{

   int i;

   if (scanf("%d%d", &n, &m) == EOF)

  {

       return 0;

  }

   for (i = 0; i < n; i++)

  {

       scanf("%d", &num[i]);

  }

   return 1;

}

int main()

{

   while (read_data())

  {

       select_combination(0, 0);

  }

   return 0;

}

/*

因为在组合生成过程中引入了变量 p,保证了每次填入的数字在num中的下标是递增的,所以不需要使用used进行标记,共C(n, m)种组合。*/

//全组合

/*

* 输入n个数,求这n个数构成的集合的所有子集。

* 输入样例:

* 3

* 1 2 3

* 输出样例:

* 1

* 1 2

* 1 2 3

* 1 3

* 2

* 2 3

* 3

*/

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

Page 68: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

#define MAX_N 10

int n;          // 共n个数int rcd[MAX_N]; // 记录每个位置填的数int num[MAX_N]; // 存放输入的n个数

void full_combination(int l, int p)

{

   int i;

   for (i = 0; i < l; i++)             // 每次进入递归函数都输出   {

       printf("%d", rcd[i]);

       if (i < l-1)

      {

           printf(" ");

      }

  }

   printf("\n");

   for (i = p; i < n; i++)             // 循环同样从p开始,但结束条件变为i>=n

  {

       rcd[l] = num[i];                // 在l位置放上该数        full_combination(l + 1, i + 1); // 填下一个位置   }

}

int read_data()

{

   int i;

   if (scanf("%d", &n) == EOF)

  {

       return 0;

  }

   for (i = 0; i < n; i++)

  {

       scanf("%d", &num[i]);

  }

   return 1;

}

int main()

{

   while (read_data())

  {

       full_combination(0, 0);

  }

   return 0;

}

/*

全组合,共2^n种,包含空集和自身。与全排列一样,若输入的n个数有重复, 那么在输出的2^n种组合中,必然存在重复的项。避免重复的方法与不重复排列算法中使用的类似。*/

//不重复组合

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

Page 69: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

/*

* 输入n个数,求这n个数构成的集合的所有子集,不允许输出重复的项。

* 输入样例:

* 3

* 1 1 3

* 输出样例:

* 1

* 1 1

* 1 1 3

* 1 3

* 3

*/

#define MAX_N 10

int n, m;           // 输入n个数,其中本质不同的有m个int rcd[MAX_N];     // 记录每个位置填的数int used[MAX_N];    // 标记m个数可以使用的次数int num[MAX_N];     // 存放输入中本质不同的m个数

void unrepeat_combination(int l, int p)

{

   int i;

   for (i = 0; i < l; i++)     // 每次都输出   {

       printf("%d", rcd[i]);

       if (i < l - 1)

      {

           printf(" ");

      }

  }

   printf("\n");

   for (i = p; i < m; i++)     // 循环依旧从p开始,枚举剩下的本质不同的数   {

       if (used[i] > 0)        // 若还可以用, 则可用次数减       {

           used[i]--;

           rcd[l] = num[i];    // 在l位置放上该            unrepeat_combination(l+1, i);   // 填下一个位置            used[i]++;          //可用次数恢复       }

  }

}

int read_data()

{

   int i, j, val;

   if (scanf("%d", &n) == EOF)

  {

       return 0;

  }

   m = 0;

   for (i = 0; i < n; i++)

  {

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

Page 70: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

求逆元

       scanf("%d", &val);

       for (j = 0; j < m; j++)

      {

           if (num[j] == val)

          {

               used[j]++;

               break;

          }

      }

       if (j == m)

      {

           num[m] = val;

           used[m++] = 1;

      }

  }

   return 1;

}

int main()

{

   while (read_data())

  {

       unrepeat_combination(0, 0);

  }

   return 0;

}

//需要注意的是递归调用时,第二个参数是i,不再是全组合中的i+1!

/*

应用

搜索问题中有很多本质上就是排列组合问题,只不过加上了某些剪枝和限制条件。解这类题目的基本算法框架常常是类循环排列、全排列、一般组合或全组 合。而不重复排列与不重复组合则是两种非常有效的剪枝技巧。*/

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466

467

468

469

470

471

472

473

474

475

476

477

478

479

480

481

482

483

484

485

//扩展欧几里得法

/*

* 扩展欧几里得法(求ax + by = gcd) */

// 返回d = gcd(a, b);和对应于等式ax + by = d中的x、y

long long extendGcd(long long a, long long b, long long &x, long long &y)

{

   if (a == 0 && b == 0)

  {

       return -1;  // 无最大公约数   }

   if (b == 0)

  {

       x = 1;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

Page 71: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       y = 0;

       return a;

  }

   long long d = extendGcd(b, a % b, y, x);

   y -= a / b * x;

   return d;

}

// 求逆元 ax = 1(mod n)

long long modReverse(long long a, long long n)

{

   long long x, y;

   long long d = extendGcd(a, n, x, y);

   if (d == 1)

  {

       return (x % n + n) % n;

  }

   else

  {

       return -1;  // 无逆元   }

}

//简洁写法

/*

* 简洁写法I

* 只能求a < m的情况,且a与m互质 * 求ax = 1(mod m)的x值,即逆元(0 < a < m)

*/

long long inv(long long a, long long m)

{

   if (a == 1)

  {

       return 1;

  }

   return inv(m % a, m) * (m - m / a) % m;

}

//欧拉函数法(求阶乘逆元)

typedef long long ll;

const ll MOD = 1e9 + 7;     // 必须为质数才管用const ll MAXN = 1e5 + 3;

ll fac[MAXN];       // 阶乘ll inv[MAXN];       // 阶乘的逆元

ll QPow(ll x, ll n)

{

   ll ret = 1;

   ll tmp = x % MOD;

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

Page 72: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

FWT

   while (n)

  {

       if (n & 1)

      {

           ret = (ret * tmp) % MOD;

      }

       tmp = tmp * tmp % MOD;

       n >>= 1;

  }

   return ret;

}

void init()

{

   fac[0] = 1;

   for (int i = 1; i < MAXN; i++)

  {

       fac[i] = fac[i - 1] * i % MOD;

  }

   inv[MAXN - 1] = QPow(fac[MAXN - 1], MOD - 2);

   for (int i = MAXN - 2; i >= 0; i--)

  {

       inv[i] = inv[i + 1] * (i + 1) % MOD;

  }

}

//线性预处理逆元inv[1] =1;

for (int i = 2; i < N; ++i) inv[i] = inv[p % i] * (p - p / i) % p;

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

/*

* FWT(快速沃尔什变化)-Xor

* MOD:1e9 + 7, INV_2:2关于MOD的逆元 * N:2的整次幂(不够就向上取整)

*/

typedef long long ll;

const int MOD = 1e9 + 7;

const int INV_2 = 5e8 + 4;

inline void FWT(int c[], int N, int tf_utf)    // tf_utf 1:tf; 0:utf

{

   for (int i = 1; i < N; i <<= 1)

  {

       int tmp = i << 1;

       for (int j = 0; j < N; j += tmp)

      {

           for (int k = 0; k < i; k++)

          {

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

Page 73: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

整数划分

               int x = c[j + k], y = c[j + k + i];

               if (tf_utf)

              {

                   c[j + k] = x + y;

                   if (c[j + k] >= MOD)

                  {

                       c[j + k] -= MOD;

                  }

                   c[j + k + i] = x - y;

                   if (c[j + k + i] < 0)

                  {

                       c[j + k + i] += MOD;

                  }

              }

               else

              {

                   c[j + k] = (ll)(x + y) * INV_2 % MOD;

                   c[j + k + i] = (ll)(x - y + MOD) * INV_2 % MOD;

              }

          }

      }

  }

}

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

/*整数划分(五边形定理)

   P(n) = ∑{P(n - k(3k - 1) / 2 + P(n - k(3k + 1) / 2 | k ≥ 1}

   n < 0时,P(n) = 0, n = 0时, P(n) = 1即可*/

// 划分元素可重复任意次#define f(x) (((x) * (3 * (x) - 1)) >> 1)

#define g(x) (((x) * (3 * (x) + 1)) >> 1)

const int MAXN = 1e5 + 10;

const int MOD = 1e9 + 7;

int n, ans[MAXN];

int main()

{

   scanf("%d", &n);

   ans[0] = 1;

   for (int i = 1; i <= n; ++i)

  {

       for (int j = 1; f(j) <= i; ++j)

      {

           if (j & 1)

          {

               ans[i] = (ans[i] + ans[i - f(j)]) % MOD;

          }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

Page 74: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

           else

          {

               ans[i] = (ans[i] - ans[i - f(j)] + MOD) % MOD;

          }

      }

       for (int j = 1; g(j) <= i; ++j)

      {

           if (j & 1)

          {

               ans[i] = (ans[i] + ans[i - g(j)]) % MOD;

          }

           else

          {

               ans[i] = (ans[i] - ans[i - g(j)] + MOD) % MOD;

          }

      }

  }

   printf("%d\n", ans[n]);

   return 0;

}

//整数划分(五边形定理拓展)

//F(n, k) = P(n) - 划分元素重复次数≥k次的情况。

// 问一个数n能被拆分成多少种情况// 且要求拆分元素重复次数不能≥k

const int MOD = 1e9 + 7;

const int MAXN = 1e5 + 10;

int ans[MAXN];

// 此函数求ans[]效率比上一个代码段中求ans[]效率高很多void init()

{

   memset(ans, 0, sizeof(ans));

   ans[0] = 1;

   for (int i = 1; i < MAXN; ++i)

  {

       ans[i] = 0;

       for (int j = 1; ; j++)

      {

           int tmp = (3 * j - 1) * j / 2;

           if (tmp > i)

          {

               break;

          }

           int tmp_ = ans[i - tmp];

           if (tmp + j <= i)

          {

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

Page 75: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

               tmp_ = (tmp_ + ans[i - tmp - j]) % MOD;

          }

           if (j & 1)

          {

               ans[i] = (ans[i] + tmp_) % MOD;

          }

           else

          {

               ans[i] = (ans[i] - tmp_ + MOD) % MOD;

          }

      }

  }

   return ;

}

int solve(int n, int k)

{

   int res = ans[n];

   for (int i = 1; ; i++)

  {

       int tmp = k * i * (3 * i - 1) / 2;

       if (tmp > n)

      {

           break;

      }

       int tmp_ = ans[n - tmp];

       if (tmp + i * k <= n)

      {

           tmp_ = (tmp_ + ans[n - tmp - i * k]) % MOD;

      }

       if (i & 1)

      {

           res = (res - tmp_ + MOD) % MOD;

      }

       else

      {

           res = (res + tmp_) % MOD;

      }

  }

   return res;

}

int main(int argc, const char * argv[])

{

   init();

   int T, n, k;

   cin >> T;

   while (T--)

  {

       cin >> n >> k;

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

Page 76: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

莫比乌斯反演

       cout << solve(n, k) << '\n';

  }

   return 0;

}

134

135

136

137

138

/*

* 莫比乌斯反演公式 * 线性筛法求解积性函数(莫比乌斯函数) */

const int MAXN = 1000000;

bool check[MAXN + 10];

int prime[MAXN + 10];

int mu[MAXN + 10];

void Moblus()

{

   memset(check, false, sizeof(check));

   mu[1] = 1;

   int tot = 0;

   for (int i = 2; i <= MAXN; i++)

  {

       if (!check[i])

      {

           prime[tot++] = i;

           mu[i] = -1;

      }

       for (int j = 0; j < tot; j++)

      {

           if (i * prime[j] > MAXN)

          {

               break;

          }

           check[i * prime[j]] = true;

           if (i % prime[j] == 0)

          {

               mu[i * prime[j]] = 0;

               break;

          }

           else

          {

               mu[i * prime[j]] = -mu[i];

          }

      }

  }

}

//单独求解int MOD(int a, int b)

{

   return a - a / b * b;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

Page 77: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

扩展Baby-Step Giant-Step

int miu(int n)

{

   int cnt, k = 0;

   for (int i = 2; i * i <= n; i++)

  {

       if (MOD(n, i))

      {

           continue;

      }

       cnt = 0;

       k++;

       while (MOD(n, i) == 0)

      {

           n /= i;

           cnt++;

      }

       if (cnt >= 2)

      {

           return 0;

      }

  }

   if (n != 1)

  {

       k++;

  }

   return MOD(k, 2) ? -1 : 1;

}

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

//求 x^y = z(mod p) 给出 x,z,p 求y

//扩展BSGS 可以用来求 GCD(a, p) != 1

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const ll MOD = 100007;

ll hs[MOD + 100], id[MOD + 100];

ll find(ll x)

{

   ll t = x % MOD;

   while(hs[t] != x && hs[t] != -1) t = (t + 1) % MOD;

   return t;

}

void insert(ll x, ll ii)

{

   ll pos = find(x);

   if(hs[pos] == -1){

       hs[pos] = x;

       id[pos] = ii;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

Page 78: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

  }

}

ll get(ll x)

{

   ll pos = find(x);

   return hs[pos] == x ? id[pos] : -1;

}

ll ex_gcd(ll a, ll b, ll& x, ll& y)

{

   if(b == 0) {

       x = 1, y = 0;

       return a;

  }

   ll d = ex_gcd(b, a % b, y, x);

   y -= a / b * x;

   return d;

}

ll inv(ll a, ll p)

{

   ll d, x, y;

   d = ex_gcd(a, p, x, y);

   return d == 1 ? (x % p + p) % p : -1;

}

ll BSGS(ll a, ll b, ll p)

{

   memset(hs, -1, sizeof(hs));

   memset(id, -1, sizeof(id));

   ll m = (ll)ceil(sqrt(p + 0.5));

   ll tmp = 1;

   for(ll i = 0; i < m; i++) {

       insert(tmp, i);

       tmp = tmp * a % p;

  }

   ll base = inv(tmp, p);

   ll res = b, z;

   for(ll i = 0; i < m; i++) {

       if((z = get(res)) != -1) return i * m + z;

       res = res * base % p;

  }

   return -1;

}

ll gcd(ll x, ll y)

{

   return y == 0 ? x : gcd(y, x % y);

}

ll solve(ll a, ll b, ll p)

{

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

Page 79: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

多项式求根

   ll tmp = 1;

   for(int i = 0; i <= 50; ++ i) {

       if(tmp == b) return i;

       tmp = tmp * a % p;

  }

   ll cnt = 0, d = 1 % p;

   while((tmp = gcd(a, p)) != 1) {

       if(b % tmp) return -1;

       b /= tmp;

       p /= tmp;

       d = a / tmp * d % p;

       cnt++;

  }

   b = b * inv(d, p) % p;

   ll ans = BSGS(a, b, p);

   if(ans == -1) return -1;

   else return ans + cnt;

}

int main()

{

   ll a, b, p;

   while(~scanf("%lld%lld%lld", &a, &p, &b) && (a || p || b)){

       ll ans = solve(a, b % p, p);

       if(ans == -1) printf("No Solution\n");

       else printf("%lld\n", ans);

  }

   return 0;

}

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

//多项式求根(牛顿法)

/*

* 牛顿法解多项式的根 * 输入:多项式系数c[],多项式度数n,求在[a,b]间的根 * 输出:根 要求保证[a,b]间有根 */

double fabs(double x)

{

   return (x < 0) ? -x : x;

}

double f(int m, double c[], double x)

{

   int i;

   double p = c[m];

   for (i = m; i > 0; i--)

  {

       p = p * x + c[i - 1];

  }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

Page 80: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

   return p;

}

int newton(double x0, double *r, double c[], double cp[], int n, double a, double

b, double eps)

{

   int MAX_ITERATION = 1000;

   int i = 1;

   double x1, x2, fp, eps2 = eps / 10.0;

   x1 = x0;

   while (i < MAX_ITERATION)

  {

       x2 = f(n, c, x1);

       fp = f(n - 1, cp, x1);

       if ((fabs(fp) < 0.000000001) && (fabs(x2) > 1.0))

      {

           return 0;

      }

       x2 = x1 - x2 / fp;

       if (fabs(x1 - x2) < eps2)

      {

           if (x2 < a || x2 > b)

          {

               return 0;

          }

           *r = x2;

           return 1;

      }

       x1 = x2;

       i++;

  }

   return 0;

}

double Polynomial_Root(double c[], int n, double a, double b, double eps)

{

   double *cp;

   int i;

   double root;

   cp = (double *)calloc(n, sizeof(double));

   for (i = n - 1; i >= 0; i--)

  {

       cp[i] = (i + 1) * c[i + 1];

  }

   if (a > b)

  {

       root = a;

       a = b;

       b = root;

  }

   if ((!newton(a, &root, c, cp, n, a, b, eps)) && (!newton(b, &root, c, cp, n, a,

b, eps)))

  {

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

Page 81: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

星期问题

       newton((a + b) * 0.5, &root, c, cp, n, a, b, eps);

  }

   free(cp);

   if (fabs(root) < eps)

  {

       return fabs(root);

  }

   else

       return root;

}

73

74

75

76

77

78

79

80

81

82

/*

星期问题

基姆拉尔森公式:

   W = (D + 2 * M + 3 * (M + 1) \ 5 + Y + Y \ 4 - Y \ 100 + Y \ 400) Mod 7

基姆拉尔森公式的计算结果是0,1,2,3,4,5,6 七种可能;结果的对应关系:0:星期一1:星期二2:星期三3:星期四4:星期五5:星期六6:星期日*/

/*

* 已知1752年9月3日是Sunday,并且日期控制在1700年2月28日后 */

char name[][15] = { "monday", "tuesday", "wednesday", "thursday", "friday",

"saturday", "sunday"};

int main()

{

   int d, m, y, a;

   printf("Day: ");

   scanf("%d", &d);

   printf("Month: ");

   scanf("%d", &m);

   printf("Year: ");

   scanf("%d", &y);

   // 1月2月当作前一年的13,14月    if (m == 1 || m == 2)

  {

       m += 12;

       y--;

  }

   // 判断是否在1752年9月3日之前,实际上合并在一起倒更加省事

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

Page 82: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

汉诺塔

   if ((y < 1752) || (y == 1752 && m < 9) || (y == 1752 && m == 9 && d < 3))

  {

       // 因为日期控制在1700年2月28日后,所以不用考虑整百年是否是闰年        a = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 + 5) % 7;

  }

   else

  {

       // 这里需要考虑整百年是否是闰年的情况        a = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7;  //

实际上这个可以当做公式背下来   }

   printf("it's a %s\n", name[a]);

   return 0;

}

40

41

42

43

44

45

46

47

48

49

50

51

52

/*

汉诺塔

1,2,…,n表示n个盘子.数字大盘子就大.

n个盘子放在第1根柱子上.大盘不能放在小盘上.

在第1根柱子上的盘子是a[1],a[2],…,a[n].a[1]=n,a[2]=n-1,…,a[n]=1.

即a[1]是最下面的盘子.把n个盘子移动到第3根柱子.

每次只能移动1个盘子,且大盘不能放在小盘上.问第m次移动的是哪一个盘子,从哪根柱子移到哪根柱子.

例如:n=3,m=2.回答是 :2 1 2,即移动的是2号盘,从第1根柱子移动到第2根柱子.

*/

/*

* 汉诺塔 * 一号柱有n个盘子,叫做源柱.移往3号柱,叫做目的柱.2号柱叫做中间柱.

* 全部移往3号柱要f(n)=(2^n)-1次.

* 最大盘n号盘在整个移动过程中只移动一次,n-1号移动2次,i号盘移动2^(n-i)次.

* 1号盘移动次数最多,每2次移动一次.

* 第2k+1次移动的是1号盘,且是第k+1次移动1号盘.第4k+2次移动的是2号盘,且是第k+1次移动2号盘.

* 第(2^s)k+2^(s-1)移动的是s号盘,这时s号盘已被移动了k+1次.每2^s次就有一次是移动s号盘.

* 第一次移动s号盘是在第2^(s-1)次.

* 第二次移动s号盘是在第2^s+2^(s-1)次.

* ......

* 第k+1次移动s号盘是在第k*2^s+2^(s-1)次.1--2--3--1叫做顺时针方向,1--3--2--1叫做逆时针方向.

* 最大盘n号盘只移动一次:1--3,它是逆时针移动.

* n-1移动2次:1--2--3,是顺时针移动.

* 如果n和k奇偶性相同,则k号盘按逆时针移动,否则顺时针.

*/

int main()

{

   int i, k;

   scanf("%d", &k);

   for (i = 0; i < k; i++)

  {

       int n, l;

       __int64_t m, j;

       __int64_t s, t;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

Page 83: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

斐波那契数列

       scanf("%d%lld", &n, &m);

       s = 1;

       t = 2;

       for (l = 1; l <= n; l++)

      {

           if (m % t == s)

          {

               break;

          }

           s = t;

           t *= 2;

      }

       printf("%d ", l);

       j = m / t;

       if (n % 2 == l % 2)

      {   // 逆时针            if ((j + 1) % 3 == 0)

          {

               printf("2 1\n");

          }

           if ((j + 1) % 3 == 1)

          {

               printf("1 3\n");

          }

           if ((j + 1) % 3 == 2)

          {

               printf("3 2\n");

          }

      }

       else

      {   // 逆时针            if ((j + 1) % 3 == 0)

          {

               printf("3 1\n");

          }

           if ((j + 1) % 3 == 1)

          {

               printf("1 2\n");

          }

           if ((j + 1) % 3 == 2)

          {

               printf("2 3\n");

          }

      }

  }

   return 0;

}

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

//矩阵原理单独求解

/*

1

2

3

Page 84: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

* 求斐波那契数列第N项,模MOD

*/

#define mod(a, m) ((a) % (m) + (m)) % (m)

const int MOD = 1e9 + 9;

struct MATRIX

{

   long long a[2][2];

};

MATRIX a;

long long f[2];

void ANS_Cf(MATRIX a)

{

   f[0] = mod(a.a[0][0] + a.a[1][0], MOD);

   f[1] = mod(a.a[0][1] + a.a[1][1], MOD);

   return ;

}

MATRIX MATRIX_Cf(MATRIX a, MATRIX b)

{

   MATRIX ans;

   int k;

   for (int i = 0; i < 2; i++)

  {

       for (int j = 0; j < 2; j++)

      {

           ans.a[i][j] = 0;

           k = 0;

           while (k < 2)

          {

               ans.a[i][j] += a.a[k][i] * b.a[j][k];

               ans.a[i][j] = mod(ans.a[i][j], MOD);

               ++k;

          }

      }

  }

   return ans;

}

MATRIX MATRIX_Pow(MATRIX a, long long n)

{

   MATRIX ans;

   ans.a[0][0] = 1;

   ans.a[1][1] = 1;

   ans.a[0][1] = 0;

   ans.a[1][0] = 0;

   while (n)

  {

       if (n & 1)

      {

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

Page 85: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

1/n循环节长度

           ans = MATRIX_Cf(ans, a);

      }

       n = n >> 1;

       a = MATRIX_Cf(a, a);

  }

   return ans;

}

int main()

{

   long long n;

   while (cin >> n)

  {

       if (n == 1)

      {

           cout << '1' << '\n';

           continue;

      }

       a.a[0][0] = a.a[0][1] = a.a[1][0] = 1;

       a.a[1][1] = 0;

       a = MATRIX_Pow(a, n - 2);

       ANS_Cf(a);

       cout << f[0] << '\n';

  }

   return 0;

}

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

//1/n循环节长度

/*

* 求1/i的循环节长度的最大值,i<=n

*/

const int MAXN = 1005;

int res[MAXN];  // 循环节长度

int main()

{

   memset(res, 0, sizeof(res));

   int i, temp, j, n;

   for (temp = 1; temp <= 1000; temp++)

  {

       i = temp;

       while (i % 2 == 0)

      {

           i /= 2;

      }

       while (i % 5 == 0)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

Page 86: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

矩阵相关

      {

           i /= 5;

      }

       n = 1;

       for (j = 1; j <= i; j++)

      {

           n *= 10;

           n %= i;

           if (n == 1)

          {

               res[temp] = j;

               break;

          }

      }

  }

   int max_re;

   while (cin >> n)

  {

       max_re = 1;

       for (i = 1; i <= n; i++)

      {

           if (res[i] > res[max_re])

          {

               max_re = i;

          }

      }

       cout << max_re << endl;

  }

   return 0;

}

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

/*

* 矩阵乘法 n*n矩阵乘法 */

#define MAXN 111

#define mod(x) ((x) % MOD)

#define MOD 1000000007

#define LL long long

int n;

struct mat

{

   int m[MAXN][MAXN];

};

// 矩阵乘法mat operator * (mat a, mat &b)

{

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

Page 87: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

   mat ret;

   memset(ret.m, 0, sizeof(ret.m));

   for (int k = 0; k < n; k++)

  {

       for (int i = 0; i < n; i++)

      {

           if (a.m[i][k])

          {

               for (int j = 0; j < n; j++)

              {

                   ret.m[i][j] = mod(ret.m[i][j] + (LL)a.m[i][k] * b.m[k][j]);

              }

          }

      }

  }

   return ret;

}

//矩阵乘法 + 判等/*

* AB == C ???

*/

struct Matrix

{

   Type mat[MAXN][MAXN];

   int n, m;

   Matrix()

  {

       n = m = MAXN;

       memset(mat, 0, sizeof(mat));

  }

   Matrix(const Matrix &a)

  {

       set_size(a.n, a.m);

       memcpy(mat, a.mat, sizeof(a.mat));

  }

   Matrix & operator = (const Matrix &a)

  {

       set_size(a.n, a.m);

       memcpy(mat, a.mat, sizeof(a.mat));

       return *this;

  }

   void set_size(int row, int column)

  {

       n = row;

       m = column;

  }

   friend Matrix operator * (const Matrix &a, const Matrix &b)

  {

       Matrix ret;

       ret.set_size(a.n, b.m);

       for (int i = 0; i < a.n; ++i)

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

Page 88: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

      {

           for (int k = 0; k < a.m; ++k)

          {

               if (a.mat[i][k])

              {

                   for (int j = 0; j < b.m; ++j)

                  {

                       if (b.mat[k][j])

                      {

                           ret.mat[i][j] = ret.mat[i][j] + a.mat[i][k] * b.mat[k]

[j];

                      }

                  }

              }

          }

      }

       return ret;

  }

   friend bool operator == (const Matrix &a, const Matrix &b)

  {

       if (a.n != b.n || a.m != b.m)

      {

           return false;

      }

       for (int i = 0; i < a.n; ++i)

      {

           for (int j = 0; j < a.m; ++j)

          {

               if (a.mat[i][j] != b.mat[i][j])

              {

                   return false;

              }

          }

      }

       return true;

  }

};

//矩阵快速幂

/*

* 矩阵快速幂 n*n矩阵的x次幂 */

#define MAXN 111

#define mod(x) ((x) % MOD)

#define MOD 1000000007

#define LL long long

int n;

struct mat

{

   int m[MAXN][MAXN];

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

Page 89: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

} unit; // 单元矩阵

// 矩阵乘法mat operator * (mat a, mat &b)

{

   mat ret;

   memset(ret.m, 0, sizeof(ret.m));

   for (int k = 0; k < n; k++)

  {

       for (int i = 0; i < n; i++)

      {

           if (a.m[i][k])

          {

               for (int j = 0; j < n; j++)

              {

                   ret.m[i][j] = mod(ret.m[i][j] + (LL)a.m[i][k] * b.m[k][j]);

              }

          }

      }

  }

   return ret;

}

void init_unit()

{

   for (int i = 0; i < MAXN; i++)

  {

       unit.m[i][i] = 1;

  }

   return ;

}

mat pow_mat(mat a, LL n)

{

   mat ret = unit;

   while (n)

  {

       if (n & 1)

      {

//           n--;

           ret = ret * a;

      }

       n >>= 1;

       a = a * a;

  }

   return ret;

}

int main()

{

   LL x;

   init_unit();

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

Page 90: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

反素数

   while (cin >> n >> x)

  {

       mat a;

       for (int i = 0; i < n; i++)

      {

           for (int j = 0; j < n; j++)

          {

               cin >> a.m[i][j];

          }

      }

       a = pow_mat(a, x);  // a矩阵的x次幂        // 输出矩阵        for (int i = 0; i < n; i++)

      {

           for (int j = 0; j < n; j++)

          {

               if (j + 1 == n)

              {

                   cout << a.m[i][j] << endl;

              }

               else

              {

                   cout << a.m[i][j] << " ";

              }

          }

      }

  }

   return 0;

}

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

//求最小的因子个数为n个正整数

typedef unsigned long long ULL;

const ULL INF = ~0ULL;

const int MAXP = 16;

int prime[MAXP] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53};

int n;

ULL ans;

void dfs(int dept, ULL tmp, int num, int pre)    // 深度/当前值/约数个数/上一个数{

   if (num > n)

  {

       return;

  }

   if (num == n && ans > tmp)

  {

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

Page 91: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       ans = tmp;

  }

   for (int i = 1; i <= pre; i++)

  {

       if (ans / prime[dept] < tmp)

      {

           break;

      }

       dfs(dept + 1, tmp *= prime[dept], num * (i + 1), i);

  }

}

int main()

{

   while (cin >> n)

  {

       ans = INF;

       dfs(0, 1, 1, 15);

       cout << ans << endl;

  }

   return 0;

}

//求n以内的因子最多的数(不止一个则取最小)

typedef long long ll;

const int MAXP = 16;

const int prime[MAXP] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47,

53};

ll n, res, ans;

void dfs(ll cur, ll num, int key, ll pre)  // 当前值/当前约数数量/当前深度/上一个数{

   if (key >= MAXP)

  {

       return ;

  }

   else

  {

       if (num > ans)

      {

           res = cur;

           ans = num;

      }

       else if (num == ans)    // 如果约数数量相同,则取较小的数       {

           res = min(cur, res);

      }

       ll i;

       for ( i = 1; i <= pre; i++)

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

Page 92: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

      {

           if (cur <= n / prime[key])  // cur*prime[key]<=n

          {

               cur *= prime[key];

               dfs(cur, num * (i + 1), key + 1, i);

          }

           else

          {

               break;

          }

      }

  }

}

void solve()

{

   res = 1;

   ans = 1;

   dfs(1, 1, 0, 15);

   cout << res << ' ' << ans << endl;

}

int main(int argc, const char * argv[])

{

   int T;

   cin >> T;

   while (T--)

  {

       cin >> n;

       solve();

  }

   return 0;

}

//反素数打表#include<cstdio>

int n,f[70]={1,2,4,6,12,24,36,48,60,120,180,240,360,720,840,

1260,1680,2520,5040,7560,10080,15120,20160,25200,27720,45360,

50400,55440,83160,110880,166320,221760,277200,332640,498960,

554400,665280,720720,1081080,1441440,2162160,2882880,3603600,

4324320,6486480,7207200,8648640,10810800,14414400,17097280,

21621600,32432400,36756720,43243200,61261200,73513440,110270160,

122522400,147026880,183783600,245044800,294053760,367567200,

551350800,698377680,735134400,1102701600,1396755360,2095133040};

int main(){

   scanf("%d",&n);

   for(int i=68;i;--i)

       if(f[i]<=n){

           printf("%d",f[i]);

           break;

      }

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

Page 93: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

容斥

}

//打表程序#include<cstdio>

#include<cstring>

#define re register int

#define rep(i,a,b) for(re i=(a);i<=(b);++(i))

#define drep(i,a,b) for(re i=(a);i>=(b);--(i))

#define min(a,b) (a<b?a:b)

const int INF=2100000000;

int pri[20]={0,2,3,5,7,11,13,17,19,23};

int f[10000];

inline void pout(){

   int cnt=0;

   int maxn=f[9999]+1;

   drep(i,9999,1){

       if(f[i]==2139062143)    continue;

       if(f[i]>maxn)    continue;

       maxn=f[i];

       printf("%d ",f[i]);

       cnt++;

       if(cnt%10==0)    putchar('\n');

  }

}

inline long long qmod(int a,int b){

   long long ans=1,m=a;

   while(b){

       if(b&1)    ans*=m;

       m*=m;

       b>>=1;

  }

   return ans;

}

inline void dfs(int i,int pr,long long res,int tim){

   if(tim>10000)    return ;

   f[tim]=min(f[tim],res);

   if(i==10)    return ;

   long long zql;

   drep(k,pr,1){

       zql=res*qmod(pri[i],k);

       if(zql>INF || zql<0)    continue;

       dfs(i+1,k,zql,tim*(k+1));

  }

}

int main(){

   memset(f,127,sizeof(f));

   f[1]=1;

   dfs(1,30,1,1);

   pout();

}

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

Page 94: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

母函数

const int MAXN = 1111;

int n;

double ans;

double p[MAXN];

void dfs(int x, int tot, double sum)    // dfs(1, 0, ?)

{

   if (x == n + 1)

  {

       if (sum == 0.0)

      {

           return ;

      }

       if (tot & 1)

      {

           ans += 1 / sum; // 公式随意变       }

       else

      {

           ans -= 1 / sum;

      }

       return ;

  }

   dfs(x + 1, tot, sum);

   dfs(x + 1, tot + 1, sum + p[x]);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

//母函数

/*

* 母函数 * c1是保存各项质量砝码可以组合的数目 * c2是中间量,保存每一次的情况 */

const int MAXN = 1e4 + 10;

int n;

int c1[MAXN];

int c2[MAXN];

int main()

{

   while (cin >> n)

  {

       for (int i = 0; i <= n; ++i)

      {

           c1[i] = 1;

           c2[i] = 0;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

Page 95: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

BM递推

      }

       for (int i = 2; i <= n; ++i)

      {

           for (int j = 0; j <= n; ++j)

          {

               for (int k = 0; k + j <= n; k += i)

              {

                   c2[j + k] += c1[j];

              }

          }

           for (int j = 0; j <= n; ++j)

          {

               c1[j] = c2[j];

               c2[j] = 0;

          }

      }

       cout << c1[n] << endl;

  }

   return 0;

}

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

#include <bits/stdc++.h>

using namespace std;

#define rep(i,a,n) for (long long i=a;i<n;i++)

#define per(i,a,n) for (long long i=n-1;i>=a;i--)

#define pb push_back

#define mp make_pair

#define all(x) (x).begin(),(x).end()

#define fi first

#define se second

#define SZ(x) ((long long)(x).size())

typedef vector<long long> VI;

typedef long long ll;

typedef pair<long long,long long> PII;

const ll mod=1e9+7;

ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1)

{if(b&1)res=res*a%mod;a=a*a%mod;}return res;}

// head

long long _,n;

namespace linear_seq

{

   const long long N=10010;

   ll res[N],base[N],_c[N],_md[N];

   vector<long long> Md;

   void mul(ll *a,ll *b,long long k)

  {

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

Page 96: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       rep(i,0,k+k) _c[i]=0;

       rep(i,0,k) if (a[i]) rep(j,0,k)

           _c[i+j]=(_c[i+j]+a[i]*b[j])%mod;

       for (long long i=k+k-1;i>=k;i--) if (_c[i])

           rep(j,0,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;

       rep(i,0,k) a[i]=_c[i];

  }

   long long solve(ll n,VI a,VI b)

  { // a 系数 b 初值 b[n+1]=a[0]*b[n]+...

//       printf("%d\n",SZ(b));

       ll ans=0,pnt=0;

       long long k=SZ(a);

       assert(SZ(a)==SZ(b));

       rep(i,0,k) _md[k-1-i]=-a[i];_md[k]=1;

       Md.clear();

       rep(i,0,k) if (_md[i]!=0) Md.push_back(i);

       rep(i,0,k) res[i]=base[i]=0;

       res[0]=1;

       while ((1ll<<pnt)<=n) pnt++;

       for (long long p=pnt;p>=0;p--)

      {

           mul(res,res,k);

           if ((n>>p)&1)

          {

               for (long long i=k-1;i>=0;i--) res[i+1]=res[i];res[0]=0;

               rep(j,0,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;

          }

      }

       rep(i,0,k) ans=(ans+res[i]*b[i])%mod;

       if (ans<0) ans+=mod;

       return ans;

  }

   VI BM(VI s)

  {

       VI C(1,1),B(1,1);

       long long L=0,m=1,b=1;

       rep(n,0,SZ(s))

      {

           ll d=0;

           rep(i,0,L+1) d=(d+(ll)C[i]*s[n-i])%mod;

           if (d==0) ++m;

           else if (2*L<=n)

          {

               VI T=C;

               ll c=mod-d*powmod(b,mod-2)%mod;

               while (SZ(C)<SZ(B)+m) C.pb(0);

               rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;

               L=n+1-L; B=T; b=d; m=1;

          }

           else

          {

               ll c=mod-d*powmod(b,mod-2)%mod;

               while (SZ(C)<SZ(B)+m) C.pb(0);

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

Page 97: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

图论 SPFA多源最短路径

               rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;

               ++m;

          }

      }

       return C;

  }

   long long gao(VI a,ll n)

  {

       VI c=BM(a);

       c.erase(c.begin());

       rep(i,0,SZ(c)) c[i]=(mod-c[i])%mod;

       return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));

  }

};

int main()

{

   while(~scanf("%I64d", &n))

  {   printf("%I64d\n",linear_seq::gao(VI{1,5,11,36,95,281,781,2245,6336,18061,

51205},n-1));

  }

}

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

const int maxn = (int)1e5 + 10;

const int Maxn = (int)2e3 + 100;

const int MOD = (int)1e8 +7;

int t, n, m, kase = 1;

int x[maxn], y[maxn], c[maxn], w[maxn];

struct node

{

int to, w;

node() {}

node(int to, int w) : to(to), w(w) {}

};

vector <node> edge[maxn];

bool Input()

{

if (t == 0) return false; t--;

__read(n), __read(m);

for (int i = 0; i <= m; i++)

edge[i].clear();

for (int i = 1; i <= n; i++)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

Page 98: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

__read(x[i]);

for (int i = 1; i <= n; i++)

__read(y[i]);

for (int i = 1; i <= n; i++)

__read(c[i]);

for (int i = 1; i <= m; i++)

__read(w[i]);

for (int i = 1; i <= n; i++)

{

edge[y[i]].pb(node(x[i], c[i]));

if (w[y[i]] == 0)

edge[0].pb(node(y[i], 0));

}

return true;

}

ll Dist[maxn];

bool used[maxn];

struct Node

{

int to;

ll cost;

Node() {}

Node(int to, ll cost) : to(to), cost(cost) {}

bool operator < (const Node& r) const

{

return cost > r.cost;

}

};

void SPFA()

{

for (int i = 1; i <= m; i++)

Dist[i] = INFLL, used[i] = false; Dist[0] = 0; used[0] = true;

queue <int> q; q.push(0);

while (!q.empty())

{

int u = q.front(); q.pop();

used[u] = false;

for (auto it : edge[u])

{

if (Dist[it.to] > Dist[u] + it.w)

{

Dist[it.to] = Dist[u] + it.w;

if (used[it.to] == false)

{

q.push(it.to);

used[it.to] = true;

}

}

}

}

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

Page 99: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

Floyd至少经过k条路

}

void Solve()

{

Dijkstra();

ll ans = 0;

for (int i = 1; i <= m; i++)

{

if (w[i] == 2)

{

if (Dist[i] == INFLL)

{

ans = -1;

break;

}

ans += Dist[i];

}

}

printf("Case #%d: %lld\n", kase++, ans);

}

/*

曹操往x战场派兵,那么y战场就多一只袁绍的兵 可以理解成 x战场曹兵+1 y战场曹兵-1

x与y连一条边, 如果y战场是等级为0的 那么无所谓  

也就是说 要找到一条 从x到它最近的等级为0的战场的一条最短路径 就是 多源最短路径

把边求逆 用spfa松弛   为什么Dijkstra 是错误的,, 我也不知道 可能是多源的问题 增加一个源点,和所有等级为0的战场连一条边权为0的边*/

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

//至少经过k条路,k很大时,考虑分块  

//n = 100x + b

inline void Floyd()

{

for (int l = 2; l <= 200; ++l)

for (int k = 1; k <= n; ++k)

for (int i = 1; i <= n; ++i)

for (int j = 1; j <= n; ++j)

G[l][i][j] = min(G[l][i][j], G[l - 1][i][k] + G[1][k][j]);

for (int i = 1; i <= n; ++i)

for (int j = 1; j <= n; ++j)

for (int l = 199; l >= 0; --l)

G[l][i][j] = min(G[l][i][j], G[l + 1][i][j]); // at least K roads;

for (int i = 1; i <= n; ++i)

for (int j = 1; j <= n; ++j)

dp[1][i][j] = G[100][i][j];

for (int l = 2; l <= 100; ++l)

for (int k = 1; k <= n; ++k)

for (int i = 1; i <= n; ++i)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

Page 100: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

 

第k短路

for (int j = 1; j <= n; ++j)

dp[l][i][j] = min(dp[l][i][j], dp[l - 1][i][k] + dp[1][k][j]);

}

20

21

22

//Dijkstra

/*

* Dijkstra变形,可以证明每个点经过的次数为小于等于K, * 所有Dijkstra的数组dist由一维变为二维,记录经过该点 * 1次、2次......k次的最小值 * 输出dist[n - 1][k]即可 */

int g[1010][1010];

int n, m, x;

const int INF = 0x3f3f3f3f;

int vis[1010];

int dist[1010][20];

int main(int argc, const char * argv[])

{

   while (cin >> n >> m >> x)

  {

       //初始化        memset(g, 0x3f, sizeof(g));

       memset(dist, 0x3f, sizeof(dist));

       memset(vis, 0, sizeof(vis));

       for (int i = 0; i < m; i++)

      {

           int p, q, r;

           cin >> p >> q >> r;

           if (r < g[p][q])

          {

               g[p][q] = r;

          }

      }

       dist[1][0] = 0;

       dist[0][0] = INF;

       while (1)

      {

           int k = 0;

           for (int i = 1; i <= n; i++)

          {

               if (vis[i] < x && dist[i][vis[i]] < dist[k][0])

              {

                   k = i;

              }

          }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

Page 101: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

           if (k == 0)

          {

               break;

          }

           if (k == n && vis[n] == x - 1)

          {

               break;

          }

           for (int i = 1; i <= n; i++)

          {

               if (vis[i] < x && dist[k][vis[k]] + g[k][i] < dist[i][x])

              {

                   dist[i][x] = dist[k][vis[k]] + g[k][i];

                   for (int j = x; j > 0; j--)

                  {

                       if (dist[i][j] < dist[i][j - 1])

                      {

                           swap(dist[i][j], dist[i][j - 1]);

                      }

                  }

              }

          }

           vis[k]++;

      }

       if (dist[n][x - 1] < INF)

      {

           cout << dist[n][x - 1] << endl;

      }

       else

      {

           cout << -1 << endl;

      }

  }

   return 0;

}

//A*

/*

* A* 估价函数 fi为到当前点走过的路经长度,hi为该点到终点的长度 * gi = hi + fi

*/

int n, m, x, ct;

int g[1010][1010];

int gr[1010][1010];

int dist[1010];

int vis[1010];

const int INF = 0x3f3f3f3f;

struct node

{

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

Page 102: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

   int id;

   int fi;

   int gi;

   friend bool operator < (node a, node b)

  {

       if (a.gi == b.gi)

      {

           return a.fi > b.fi;

      }

       return a.gi > b.gi;

  }

} s[20000010];

int init()

{

   memset(dist, 0x3f, sizeof(dist));

   for (int i = 0; i <= n; i++)

  {

       vis[i] = 1;

  }

   dist[n - 1] = 0;

   for (int i = 0; i < n; i++)

  {

       int k = n;

       for (int j = 0; j < n; j++)

      {

           if (vis[j] && dist[j] < dist[k])

          {

               k = j;

          }

      }

       if (k == n)

      {

           break;

      }

       vis[k] = 0;

       for (int j = 0; j < n; j++)

      {

           if (vis[j] && dist[k] + gr[k][j] < dist[j])

          {

               dist[j] = dist[k] + gr[k][j];

          }

      }

  }

   return 1;

}

int solve()

{

   if (dist[0] == INF)

  {

       return -1;

  }

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

Page 103: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

   ct = 0;

   s[ct].id = 0;

   s[ct].fi = 0;

   s[ct++].gi = dist[0];

   int cnt = 0;

   while (ct)

  {

       int id = s[0].id;

       int fi = s[0].fi;

       if (id == n - 1)

      {

           cnt++;

      }

       if (cnt == x)

      {

           return fi;

      }

       pop_heap(s, s + ct);

       ct--;

       for (int j = 0; j < n; j++)

      {

           if (g[id][j] < INF)

          {

               s[ct].id = j;

               s[ct].fi = fi + g[id][j];

               s[ct].gi = s[ct].fi + dist[j];

               ct++;

               push_heap(s, s + ct);

          }

      }

  }

   return -1;

}

int main()

{

   while (cin >> n >> m >> x)

  {

       memset(g, 0x3f, sizeof(g));

       memset(gr, 0x3f, sizeof(gr));

       for (int i = 0; i < n; i++)

      {

           int p, q, r;

           cin >> p >> q >> r;

           p--;

           q--;

           g[p][q] = g[p][q] <= r ? g[p][q] : r;

           gr[q][p] = gr[q][p] <= r ? gr[q][p] : r;

      }

       init();

       cout << solve() << endl;

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

Page 104: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

DSU on tree

  }

   return 0;

}

205

206

207

208

//DSU on tree

#include <bits/stdc++.h>

using namespace std;

#define N 100010

#define ll long long

int n;

int arr[N];

struct Edge

{

int to, nx;

inline Edge() {}

inline Edge(int to, int nx) : to(to), nx(nx) {}

}edge[N << 1];

int head[N], pos;

int sz[N], bigson[N];

ll ans[N], cnt[N], sum, Max;

bool used[N];

inline void Init()

{

memset(head, -1, sizeof head);

memset(bigson, 0, sizeof bigson);

memset(cnt, 0, sizeof cnt);

memset(used, false, sizeof used);

pos = 0; sz[0] = 0; Max = 0, sum = 0;

}

inline void addedge(int u, int v)

{

edge[++pos] = Edge(v, head[u]); head[u] = pos;

edge[++pos] = Edge(u, head[v]); head[v] = pos;

}

inline void Getsz(int u, int pre)

{

sz[u] = 1;

for (int it = head[u]; ~it; it = edge[it].nx)

{

int v = edge[it].to;

if (v == pre) continue;

Getsz(v, u);

sz[u] += sz[v];

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

Page 105: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

if (sz[v] > sz[bigson[u]]) bigson[u] = v;

}

}

inline void calc(int u, int pre, int val)

{

cnt[arr[u]] += val;

if (val > 0 && cnt[arr[u]] >= Max)

{

if (cnt[arr[u]] > Max)

{

sum = 0;

Max = cnt[arr[u]];

}

sum += arr[u];  

}

for (int it = head[u]; ~it; it = edge[it].nx)

{

int v = edge[it].to;

if (v == pre || used[v]) continue;

calc(v, u, val);

}

}

inline void DFS(int u, int pre, bool vis)

{

for (int it = head[u]; ~it; it = edge[it].nx)

{

int v = edge[it].to;

if (v == pre || v == bigson[u]) continue;

DFS(v, u, 0);  

}

if (bigson[u]) DFS(bigson[u], u, 1), used[bigson[u]] = true;

calc(u, pre, 1);

ans[u] = sum;

if (bigson[u]) used[bigson[u]] = false;

if (!vis) calc(u, pre, -1), Max = sum = 0;

}

inline void Run()

{

while(scanf("%d", &n) != EOF)

{

Init();

for (int i = 1; i <= n; ++i) scanf("%d", arr + i);

for (int i = 1, u, v; i < n; ++i)

{

scanf("%d%d", &u, &v);

addedge(u, v);

}

Getsz(1, 1);

DFS(1, 0, 0);

for (int i = 1; i <= n; ++i) printf("%lld%c", ans[i], " \n"[i == n]);

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

Page 106: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

 

最小生成树(森林)

}

}

int main()

{

#ifdef LOCAL

freopen("Test.in", "r", stdin);

#endif

Run();

return 0;

}

100

101

102

103

104

105

106

107

108

109

110

111

112

113

//MST

/*

* Minimal Steiner Tree

* G(V, E), A是V的一个子集, 求至少包含A中所有点的最小子树.

* 时间复杂度:O(N^3+N*2^A*(2^A+N))

* INIT: d[][]距离矩阵; id[]置为集合A中点的标号;

* CALL: steiner(int n, int a);

* 给4个点对(a1,b1)...(a4,b4),

* 求min(sigma(dist[ai][bi])),其中重复的路段只能算一次.

* 这题要找出一个Steiner森林, 最后要对森林中树的个数进行枚举 */

#define typec int               // type of cost

const typec inf = 0x3f3f3f3f;   // max of cost

const typec V = 10010;

const typec A = 10;

int vis[V], id[A];              // id[]:       A中点的标号typec d[V][V], dp[1 << A][V];   // dp[i][v]:   点v到点集i的最短距离

void steiner(int n, int a)

{

   int i, j, k, mx, mk = 0, top = (1 << a);

   for (k = 0; k < n; k++)

  {

       for (i = 0; i < n; i++)

      {

           for (j = 0; j < n; j++)

          {

               if (d[i][j] > d[i][k] + d[k][j])

              {

                   d[i][j] = d[i][k] + d[k][j];

              }

          }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

Page 107: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

      }

  }

   for (i = 0; i < a; i++)

  {

       // vertex: 0 ~ n-1

       for (j = 0; j < n; j++)

      {

           dp[1 << i][j] = d[j][id[i]];

      }

  }

   for (i = 1; i < top; i++)

  {

       if (0 == (i & (i - 1)))

      {

           continue;

      }

       memset(vis, 0, sizeof(vis));

       for (k = 0; k < n; k++) // init

      {

           for (dp[i][k] = inf, j = 1; j < i; j++)

          {

               if ((i | j) == i && dp[i][k] > dp[j][k] + dp[i - j][k])

              {

                   dp[i][k] = dp[j][k] + dp[i - j][k];

              }

          }

      }

       for (j = 0; mx = inf, j < n; j++)

      {

           // update

           for (k = 0; k < n; k++)

          {

               if (dp[i][k] <= mx && 0 == vis[k])

              {

                   mx = dp[i][mk = k];

              }

          }

           for (k = 0, vis[mk] = 1; k < n; k++)

          {

               if (dp[i][mk] > dp[i][k] + d[k][mk])

              {

                   dp[i][mk] = dp[i][k] + d[k][mk];

              }

          }

      }

  }

   return ;

}

int main(int argc, const char * argv[])

{

   int n, a = 8;

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

Page 108: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

DAG的深度优先搜索标记

   int b, z, i, j, k, x = 0, y;

   // TODO: read data;

   steiner(n, a);

   // enum to find the result

   for (i = 0, b = inf; z = 0, i < 256; b > z ? b = z : b, i++)

  {

       for (j = 0; y = 0, j < 4; z += !!y * dp[y][x], j++)

      {

           for (k = 0; k < 8; k += 2)

          {

               if ((i >> k & 3) == j)

              {

                   y += 3 << k, x = id[k];

              }

          }

      }

  }

   // TODO: cout << b << endl;

   return 0;

}

/*

最小生成森林问题(K颗树)

数据结构:并查集 算法:改进Kruskal 复杂度:O(mlongm)

根据Kruskal算法思想,图中的生成树在连接完第n - 1条边前,都是一个最小生成森林,每次贪心的选择两个不属于同一连通分量的树(如果连接一个连通分量,因为不会减少块数,那么就是不合算的)且用最“便宜”的边连起来,连接n - 1次后就形成了一棵MST,n - 2次就形成了一个两棵树的最小生成森林,n - 3、……、n -

k次后,就形成了k棵树的最小生成森林,也就是题目要求的解。*/

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

//DAG && DFS

/*

* DAG(有向无环图)的深度优先搜索标记 * INIT:edge[][]邻接矩阵;pre[], post[], tag全置0

* CALL:dfsTag(i, n);   pre/post:开始/结束时间 */

const int V = 1010;

int edge[V][V];

int pre[V];

int post[V];

int tag;

void dfsTag(int cur, int n)

{

   //vertex:0 ~ n - 1

   pre[cur] = ++tag;

   for (int i = 0; i < n; i++)

  {

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

Page 109: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

最大团问题

       if (edge[cur][i])

      {

           if (0 == pre[i])

          {

               std::cout << "Three Edge!" << '\n';

               dfsTag(i, n);

          }

           else

          {

               if (0 == post[i])

              {

                   std::cout << "Back Edge!" << '\n';

              }

               else if (pre[i] > pre[cur])

              {

                   std::cout << "Down Edge!" << '\n';

              }

               else

              {

                   std::cout << "Cross Edge!" << '\n';

              }

          }

      }

  }

   post[cur] = ++tag;

   return ;

}

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

//DP + DFS

/*

* INIT: g[][]邻接矩阵 * CALL: res = clique(n);

*/

const int V = 10010;

int g[V][V];

int dp[V];

int stk[V][V];

int mx;

int dfs(int n, int ns, int dep)

{

   if (0 == ns)

  {

       if (dep > mx)

      {

           mx = dep;

      }

       return 1;

  }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

Page 110: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

有向图最小树形图

   int i, j, k, p, cnt;

   for (i = 0; i < ns; i++)

  {

       k = stk[dep][i];

       cnt = 0;

       if (dep + n - k <= mx)

      {

           return 0;

      }

       if (dep + dp[k] <= mx)

      {

           return 0;

      }

       for (j = i + 1; j < ns; j++)

      {

           p = stk[dep][j];

           if (g[k][p])

          {

               stk[dep + 1][cnt++] = p;

          }

      }

       dfs(n, cnt, dep + 1);

  }

   return 1;

}

int clique(int n)

{

   int i, j, ns;

   for (mx = 0, i = n - 1; i >= 0; i--)    // vertex: 0 ~ n-1

  {

       for (ns = 0, j = i + 1; j < n; j++)

      {

           if (g[i][j])

          {

               stk[1][ns++] = j;

          }

      }

       dfs(n, ns, 1);

       dp[i] = mx;

  }

   return mx;

}

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

//有向图最小树形图

/*

* 有向图最小树形图 * INIT: eg置为边表;res置为0;cp[i]置为i; * CALL: dirTree(root, nv, ne); res是结果 */

1

2

3

4

5

6

7

Page 111: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

#define typec int               // type of res

const typec V = 1010;

const typec E = 10010;

const typec inf = 0x3f3f3f3f;   // max of res

typec res, dis[V];

int to[V], cp[V], tag[V];

struct Edge

{

   int u, v;

   typec c;

} eg[E];

int iroot(int i)

{

   if (cp[i] == i)

  {

       return i;

  }

   return cp[i] = iroot(cp[i]);

}

int dirTree(int root, int nv, int ne)   // root:树根{

   // vertex:0~n-1

   int i, j, k, circle = 0;

   memset(tag, -1, sizeof(tag));

   memset(to, -1, sizeof(to));

   for (i = 0; i < nv; i++)

  {

       dis[i] = inf;

  }

   for (j = 0; j < ne; j++)

  {

       i = iroot(eg[j].u);

       k = iroot(eg[j].v);

       if (k != i && dis[k] > eg[j].c)

      {

           dis[k] = eg[j].c;

           to[k] = i;

      }

  }

   to[root] = -1;

   dis[root] = 0;

   tag[root] = root;

   for (i = 0; i < nv; i++)

  {

       if (cp[i] == i && -1 == tag[i])

      {

           j = i;

           for (; j != -1 && tag[j] == -1; j = to[j])

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

Page 112: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

          {

               tag[j] = i;

               if (j == -1)

              {

                   return 0;

              }

               if (tag[j] == i)

              {

                   circle = 1;

                   tag[j] = -2;

                   for (k = to[j]; k != j; k = to[k])

                  {

                       tag[k] = -2;

                  }

              }

          }

      }

  }

   if (circle)

  {

       for (j = 0; j < ne; j++)

      {

           i = iroot(eg[j].u);

           k = iroot(eg[j].v);

           if (k != i && tag[k] == -2)

          {

               eg[j].c -= dis[k];

          }

      }

       for (i = 0; i < nv; i++)

      {

           if (tag[i] == -2)

          {

               res += dis[i];

               tag[i] = 0;

               for (j = to[i]; j != i; j = to[j])

              {

                   res += dis[j];

                   cp[j] = i;

                   tag[j] = 0;

              }

          }

      }

       if (0 == dirTree(root, nv, ne))

      {

           return 0;

      }

  }

   else

  {

       for (i = 0; i < nv; i++)

      {

           if (cp[i] == i)

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

Page 113: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

弦图判断

          {

               res += dis[i];

          }

      }

  }

   return 1;   // 若返回0代表原图不连通}

114

115

116

117

118

119

120

//弦图判断

/*

* 弦图判断 * INIT: g[][]置为邻接矩阵;

* CALL: mcs(n); peo(n);

* 第一步: 给节点编号 mcs(n)

* 设已编号的节点集合为A, 未编号的节点集合为B

* 开始时A为空, B包含所有节点.

* for num=n-1 downto 0 do {

*     在B中找节点x, 使与x相邻的在A集合中的节点数最多,

*     将x编号为num,并从B移入A。 * }

* 第二部:检查peo(n)

* for num=0 to n-1 do {

*     对编号为num的点x,设所有编号>num且与x相邻的点集为C

*     在C中找出编号最小的节点y, *     若C中存在x != y,使得y与x之间无边,则此图不是弦图。 * }

* 检查完毕, 则此图是弦图.

*/

const int V = 10010;

int g[V][V], order[V], inv[V], tag[V];

void mcs(int n)

{

   int i, j, k;

   memset(tag, 0, sizeof(tag));

   memset(order, -1, sizeof(order));

   for (i = n - 1; i >= 0; i--)

  {   // vertex:0~n-1

       for (j = 0; order[j] >= 0; j++);

       for (k = j + 1; k < n; k++)

      {

           if (order[k] < 0 && tag[k] > tag[j])

          {

               j = k;

          }

      }

       order[j] = i, inv[i] = j;

       for (k = 0; k < n; k++)

      {

           if (g[j][k])

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

Page 114: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

弦图的 Perfect Elimination 点排列

          {

               tag[k]++;

          }

      }

  }

   return ;

}

int peo(int n)

{

   int i, j, k, w, min;

   for (i = n - 2; i >= 0; i--)

  {

       j = inv[i], w = -1, min = n;

       for (k = 0; k < n; k++)

      {

           if (g[j][k] && order[k] > order[j] && order[k] < min)

          {

               min = order[k], w=k;

          }

      }

       if (w < 0)

      {

           continue;

      }

       for (k = 0; k < n; k++)

      {

           if (g[j][k] && order[k] > order[w] && !g[k][w])

          {

               return 0;   // no

          }

      }

  }

   return 1;               // yes

}

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

//弦图的PERFECT ELIMINATION点排列

/*

* INIT: g[][]置为邻接矩阵;

* CALL: cardinality(n);tag[i]为排列中第i个点的标号;

*/

const int V = 10010;

int tag[V], g[V][V], deg[V], vis[V];

void cardinality(int n)

{

   int i, j, k;

   memset(deg, 0, sizeof(deg));

   memset(vis, 0, sizeof(vis));

   for (i = n - 1; i >= 0; i--)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

Page 115: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

稳定婚姻问题

  {

       for (j = 0, k = -1; j < n; j++)

      {

           if (0 == vis[j])

          {

               if (k == -1 || deg[j] > deg[k])

              {

                   k = j;

              }

          }

      }

       vis[k] = 1, tag[i] = k;

       for (j = 0; j<n; j++)

      {

           if (0 == vis[j] && g[k][j])

          {

               deg[j]++;

          }

      }

  }

   return ;

}

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

//稳定婚姻问题

/*

* 稳定婚姻问题O(n^2)

*/

const int N = 1001;

struct People

{

   bool state;

   int opp, tag;

   int list[N];        // man使用    int priority[N];    // woman使用,有必要的话可以和list合并,以节省空间    void Init()

  {

       state = tag = 0;

  }

} man[N], woman[N];

struct R

{

   int opp;

   int own;

} requst[N];

int n;

void Input();

void Output();

void stableMatching();

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

Page 116: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

int main()

{

   Input();

   stableMatching();

   Output();

   return 0;

}

void Input()

{

   scanf("%d\n", &n);

   int i, j, ch;

   for (i = 0; i < n; ++i)

  {

       man[i].Init();

       for(j = 0; j < n; ++j)

      {   // 按照man的意愿递减排序            scanf("%d", &ch);

           man[i].list[j] = ch - 1;

      }

  }

   for (i = 0; i < n; ++i)

  {

       woman[i].Init();

       for (j = 0; j < n; ++j)

      {   // 按照woman的意愿递减排序,但是,存储方法与man不同            scanf("%d", &ch);

           woman[i].priority[ch - 1] = j;

      }

  }

   return ;

}

void stableMatching()

{

   int k;

   for (k = 0; k < n; ++k)

  {

       int i, id = 0;

       for (i = 0; i < n; ++i)

      {

           if (man[i].state == 0)

          {

               requst[id].opp = man[i].list[man[i].tag];

               requst[id].own = i;

               man[i].tag += 1;

               ++id;

          }

      }

       if (id == 0)

      {

           break;

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

Page 117: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

拓扑排序

      }

       for (i = 0; i < id; i++)

      {

           if (woman[requst[i].opp].state == 0)

          {

               woman[requst[i].opp].opp = requst[i].opp;

               woman[requst[i].opp].state = 1;

               man[requst[i].own].state = 1;

               man[requst[i].own].opp = requst[i].opp;

          }

           else

          {

               if (woman[requst[i].opp].priority[woman[requst[i].opp].opp]

>woman[requst[i].opp].priority[requst[i].own])

              {

                   man[woman[requst[i].opp].opp].state = 0;

                   woman[requst[i].opp].opp = requst[i].own;

                   man[requst[i].own].state = 1;

                   man[requst[i].own].opp = requst[i].opp;

              }

          }

      }

  }

   return ;

}

void Output()

{

   for (int i = 0; i < n; i++)

  {

       printf("%d\n", man[i].opp + 1);

  }

   return ;

}

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

//拓扑排序

/*

* 拓扑排序 * INIT:edge[][]置为图的邻接矩阵;cnt[0...i...n-1]:顶点i的入度。 */

const int MAXV = 1010;

int edge[MAXV][MAXV];

int cnt[MAXV];

void TopoOrder(int n)

{

   int i, top = -1;

   for (i = 0; i < n; ++i)

  {

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

Page 118: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

无向图连通分支

       if (cnt[i] == 0)

      {   // 下标模拟堆栈            cnt[i] = top;

           top = i;

      }

  }

   for (i = 0; i < n; i++)

  {

       if (top == -1)

      {

           printf("存在回路\n");

           return ;

      }

       else

      {

           int j = top;

           top = cnt[top];

           printf("%d", j);

           for (int k = 0; k < n; k++)

          {

               if (edge[j][k] && (--cnt[k]) == 0)

              {

                   cnt[k] = top;

                   top = k;

              }

          }

      }

  }

}

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

/*

* 无向图连通分支(dfs/bfs邻接阵)

* DFS / BFS / 并查集 * 返回分支数,id返回1.分支数的值 * 传入图的大小n和邻接阵mat,不相邻点边权0

*/

#define MAXN 100

void search(int n, int mat[][MAXN], int* dfn, int* low, int now, int& cnt, int&

tag, int* id, int* st, int& sp)

{

   int i, j;

   dfn[st[sp++]=now] = low[now] = ++cnt;

   for (i = 0; i < n; i++)

  {

       if (mat[now][i])

      {

           if (!dfn[i])

          {

               search(n, mat, dfn, low, i, cnt, tag, id, st, sp);

               if (low[i] < low[now])

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

Page 119: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

有向图强连通分支

              {

                   low[now]=low[i];

              }

          }

           else if (dfn[i] < dfn[now])

          {

               for (j = 0; j < sp && st[j] != i; j++)

              {

                   if (j < cnt && dfn[i] < low[now])

                  {

                       low[now] = dfn[i];

                  }

              }

          }

      }

  }

   if (low[now] == dfn[now])

  {

       for (tag++; st[sp] != now; id[st[--sp]] = tag);

  }

}

int find_components(int n, int mat[][MAXN], int* id)

{

   int ret = 0, i, cnt, sp, st[MAXN], dfn[MAXN], low[MAXN];

   for (i = 0; i < n; dfn[i++] = 0);

   for (sp = cnt = i = 0; i < n; i++)

  {

       if (!dfn[i])

      {

           search(n, mat, dfn, low, i, cnt, ret, id, st, sp);

      }

  }

   return ret;

}

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

/*

* 有向图强连通分支(dfs/bfs邻接阵)O(n^2)

* 返回分支数,id返回1..分支数的值 * 传入图的大小n和邻接阵mat,不相邻点边权0

*/

#define MAXN 100

int find_components(int n, int mat[][MAXN], int* id)

{

   int ret = 0, a[MAXN], b[MAXN], c[MAXN], d[MAXN], i, j, k, t;

   for (k = 0; k < n; id[k++] = 0);

   for (k = 0; k < n; k++)

  {

       if (!id[k])

      {

           for (i = 0; i < n; i++)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

Page 120: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

有向图最小点基

          {

               a[i] = b[i] = c[i] = d[i] = 0;

          }

           a[k] = b[k] = 1;

           for (t = 1; t;)

          {

               for (t = i = 0; i < n; i++)

              {

                   if (a[i] && !c[i])

                  {

                       for (c[i] = t = 1, j = 0; j < n; j++)

                      {

                           if (mat[i][j] && !a[j])

                          {

                               a[j] = 1;

                          }

                      }

                  }

                   if (b[i] && !d[i])

                  {

                       for (d[i] = t = 1, j = 0; j < n; j++)

                      {

                           if (mat[j][i] && !b[j])

                          {

                               b[j] = 1;

                          }

                      }

                  }

              }

          }

           for (ret++, i = 0; i < n; i++)

          {

               if (a[i] & b[i])

              {

                   id[i] = ret;

              }

          }

      }

  }

   return ret;

}

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

/*

* 有向图最小点基(邻接阵)O(n^2)

* 点基B满足:对于任意一个顶点Vj,一定存在B中的一个Vi,使得Vi是Vj的前代。 * 返回点基大小和点基 传入图的大小n和邻接阵mat,不相邻点边权0 需要调用强连通分支 * find_components(n, mat, id);参考《有向图强连通分支》 */

#define MAXN 100

int base_vertex(int n, int mat[][MAXN], int* sets)

{

1

2

3

4

5

6

7

8

9

Page 121: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

Floyd求最小环

   int ret=0, id[MAXN], v[MAXN], i, j;

   j = find_components(n, mat, id);

   for (i = 0; i < j; v[i++] = 1);

   for (i = 0; i < n; i++)

  {

       for (j = 0; j < n; j++)

      {

           if (id[i] != id[j] && mat[i][j])

          {

               v[id[j] - 1] = 0;

          }

      }

  }

   for (i = 0; i < n; i++)

  {

       if (v[id[i] - 1])

      {

           v[id[sets[ret++] = i] - 1] = 0;

      }

  }

   return ret;

}

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

/*

Floyd求最小环

令e(u, v)表示u和v之间的连边,令min(u, v)表示删除u和v之间的连边之后u和v之间的最短路, 最小环则是min(u, v) + e(u, v). 时间复杂度是 O(EV^2).

改进算法在floyd的同时,顺便算出最小环g[i][j]=i, j之间的边长*/

dist:=g;

for k:=1 to n do

begin

   for i:=1 to k-1 do

     for j:=i+1 to k-1 do

       answer:=min(answer, dist[i][j]+g[i][k]+g[k][j]);

   for i:=1 to n do

     for j:=1 to n do

       dist[i][j]:=min(dist[i][j], dist[i][k]+dist[k][j]);

end;

/*

最小环改进算法的证明一个环中的最大结点为k(编号最大), 与他相连的两个点为i, j, 这个环的最短长度为g[i][k]+g[k][j]+i

到j的路径中所有结点编号都小于k的最短路径长度. 根据floyd的原理, 在最外层循环做了k-1次之后,

dist[i][j]则代表了i到j的路径中所有结点编号都小于k的最短路径综上所述,该算法一定能找到图中最小环。*/

const int INF = 0x3f3f3f3f;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

Page 122: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

const int MAXN = 110;

int n, m;               // n:节点个数, m:边的个数int g[MAXN][MAXN];      // 无向图int dist[MAXN][MAXN];   // 最短路径int r[MAXN][MAXN];      // r[i][j]: i到j的最短路径的第一步int out[MAXN], ct;      // 记录最小环

int solve(int i, int j, int k)

{   // 记录最小环    ct = 0;

   while (j != i)

  {

       out[ct++] = j;

       j = r[i][j];

  }

   out[ct++] = i;

   out[ct++] = k;

   return 0;

}

int main()

{

   while (scanf("%d%d", &n, &m) != EOF)

  {

       int i, j, k;

       for (i = 0; i < n; i++)

      {

           for (j = 0; j < n; j++)

          {

               g[i][j] = INF;

               r[i][j] = i;

          }

      }

       for (i = 0; i < m; i++)

      {

           int x, y, l;

           scanf("%d%d%d", &x, &y, &l);

           --x;

           --y;

           if (l < g[x][y])

          {

               g[x][y] = g[y][x] = l;

          }

      }

       memmove(dist, g, sizeof(dist));

       int Min = INF;              // 最小环        for (k = 0; k < n; k++)

      {                           // Floyd

           for (i = 0; i < k; i++) // 一个环中的最大结点为k(编号最大)

          {

               if (g[k][i] < INF)

              {

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

Page 123: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

树的重心

                   for (j = i + 1; j < k; j++)

                  {

                       if (dist[i][j] < INF && g[k][j] < INF && Min > dist[i][j]

+ g[k][i] + g[k][j])

                      {

                           Min = dist[i][j] + g[k][i] + g[k][j];

                           solve(i, j, k);     // 记录最小环                       }

                  }

              }

          }

           for (i = 0; i < n; i++)

          {

               if (dist[i][k] < INF)

              {

                   for (j = 0; j < n; j++)

                  {

                       if (dist[k][j] < INF && dist[i][j] > dist[i][k]+dist[k]

[j])

                      {

                           dist[i][j] = dist[i][k] + dist[k][j];

                           r[i][j] = r[k][j];

                      }

                  }

              }

          }

      }

       if (Min < INF)

      {

           for (ct--; ct >= 0; ct--)

          {

               printf("%d", out[ct] + 1);

               if (ct)

              {

                   printf(" ");

              }

          }

      }

       else

      {

           printf("No solution.");

      }

       printf("\n");

  }

   return 0;

}

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

typedef long long ll;

typedef pair<int, int> pll;

1

2

3

Page 124: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

图Hash

const int INF = 0x3f3f3f3f;

const int MAXN = 100000 + 10;

int n;

/* 树的重心 * 初始化 vis[] son[] 为 0

* 初始化 sz 为 INF

*/

int zx, sz;

int son[MAXN], vis[MAXN];

vector<pll> edge[MAXN];

void init()

{

   for (int i = 1; i <= n; i++)

  {

       edge[i].clear();

  }

   memset(vis, 0, sizeof(vis));

   sz = INF;

   zx = -1;

}

void dfs(int r)

{

   vis[r] = 1;

   son[r] = 0;

   int tmp = 0;

   for (int i = 0; i < edge[r].size(); i++)

  {

       int v = edge[r][i].second;

       if (!vis[v])

      {

           dfs(v);

           son[r] += son[v] + 1;

           tmp = max(tmp, son[v] + 1);

      }

  }

   tmp = max(tmp, n - son[r] - 1);

   if (tmp < sz)

  {

       zx = r;

       sz = tmp;

  }

}

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

//图Hash 先对边进行Hash  

#include <bits/stdc++.h>

using namespace std;

1

2

3

4

Page 125: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

#define INF 0x3f3f3f3f

#define INFLL 0x3f3f3f3f3f3f3f3f

#define ll long long

#define N 2003

typedef pair <int, int> pii;

struct simplehash

{

int len;

ll base, mod;

vector <ll> P, H;

inline simplehash() {}

inline simplehash(const int *ar, int n, ll b, ll m)

{

len = n; base = b, mod = m;

P.resize(len + 3, 1); H.resize(len + 3, 0);

for (int i = 1; i <= len; ++i) P[i] = (P[i - 1] * base) % mod;

for (int i = 1; i <= len; ++i) H[i] = (H[i - 1] + P[ar[i]]) % mod;

}

inline ll range_hash(int l, int r)

{

ll hashval = (H[r] - H[l - 1]) % mod;

return (hashval < 0 ? hashval + mod : hashval);

}

};

struct arrayhash

{

simplehash sh1, sh2;

inline arrayhash() {}

inline arrayhash(const int *ar, int n)

{

sh1 = simplehash(ar, n, 1949313259, 2091573227);

sh2 = simplehash(ar, n, 1997293877, 2117566807);

}

inline ll range_hash(int l, int r)

{

return (sh1.range_hash(l, r) << 32) ^ (sh2.range_hash(l, r));

}

};

int t, n, pos;

map <pii, int> mp;

unordered_map <ll, int> mp2;

int arr[N];

inline void Init()

{

mp.clear(); pos = 0;

mp2.clear();

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

Page 126: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

 

}

struct Edge

{

int u, v, id;

inline void scan()

{

scanf("%d%d", &u, &v);

if (u > v) swap(u, v);

if (!mp.count(pii(u, v)))

mp[pii(u, v)] = mp.size() + 1;

id = mp[pii(u, v)];

}

}edge[N];

inline void Run()

{

scanf("%d", &t);

while (t--)

{

scanf("%d", &n); Init();

for (int i = 1; i <= n; ++i)

{

edge[i].scan();

arr[i] = edge[i].id;

}

ll ans = 0;

arrayhash x = arrayhash(arr, n);

for (int i = 1; i <= n; ++i)

{

for (int j = i; j <= n; ++j)

{

ll Hash = x.range_hash(i, j);

ans += mp2[Hash]++;

}

}

printf("%lld\n", ans);

}

}

int main()

{

#ifdef LOCAL

freopen("Test.in", "r", stdin);

#endif

Run();

return 0;

}

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

Page 127: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

网络流 二分图最小割

/*

* INIT: 初始化邻接矩阵g[][]

* CALL: res = mincut(n);

* 注: Stoer-Wagner Minimum Cut;

* 找边的最小集合,若其被删去则图变得不连通(我们把这种形式称为最小割问题) */

#define typec int               // type of res

const typec inf = 0x3f3f3f3f;   // max of res

const typec maxw = 1000;        // maximum edge weight

const typec V = 10010;

typec g[V][V], w[V];

int a[V], v[V], na[V];

typec minCut(int n)

{

   int i, j, pv, zj;

   typec best = maxw * n * n;

   for (i = 0; i < n; i++)

  {

       v[i] = i;   // vertex: 0 ~ n-1

  }

   while (n > 1)

  {

       for (a[v[0]] = 1, i = 1; i < n; i++)

      {

           a[v[i]] = 0;

           na[i - 1] = i;

           w[i] = g[v[0]][v[i]];

      }

       for (pv = v[0], i = 1; i < n; i++)

      {

           for (zj = -1, j = 1; j < n; j++)

          {

               if (!a[v[j]] && (zj < 0 || w[j] > w[zj]))

              {

                   zj = j;

              }

          }

           a[v[zj]] = 1;

           if (i == n - 1)

          {

               if (best > w[zj])

              {

                   best = w[zj];

              }

               for (i = 0; i < n; i++)

              {

                   g[v[i]][pv] = g[pv][v[i]] += g[v[zj]][v[i]];

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

Page 128: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

网络流

              }

               v[zj] = v[--n];

               break;

          }

           pv = v[zj];

           for (j = 1; j < n; j++)

          {

               if(!a[v[j]])

              {

                   w[j] += g[v[zj]][v[j]];

              }

          }

      }

  }

   return best;

}

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

#include<bits/stdc++.h>

using namespace std;

const int maxn = 1e3 + 10;

const int INF = 0x3f3f3f3f;

int n, m;

struct Edge{

int from;

int to;

int cap;

int flow;

inline Edge(){}

inline Edge(int from,int to,int cap,int flow):from(from), to(to), cap(cap),

flow(flow){}

};

vector<Edge>edge;

vector<int>G[maxn];

int vis[maxn];

int d[maxn];

int cur[maxn];

int S,T;

inline void init()

{

edge.clear();

for(int i = 1; i <= n; ++i)

G[i].clear();

}

inline void addedge(int from,int to,int cap)

{

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

Page 129: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

edge.push_back(Edge(from,to,cap,0));

edge.push_back(Edge(to,from,0,0));

int len = edge.size();

G[from].push_back(len - 2);

G[to].push_back(len - 1);

}

inline bool bfs()

{

memset(d,0,sizeof d);

memset(vis,0,sizeof vis);

queue<int>q;

q.push(S);

d[S] = 1;

vis[S] = 1;

while(!q.empty())

{

int x = q.front();

q.pop();

for(int i = 0; i < G[x].size(); ++i)

{

Edge &e = edge[G[x][i]];

for(int i = 0; i < G[x].size(); ++i)

{

Edge &e = edge[G[x][i]];

if(!vis[e.to] && e.cap > e.flow)

{

vis[e.to] = 1;

d[e.to] = d[x] + 1;

q.push(e.to);

}

}

}

}

return vis[T];

}

inline int dfs(int x,int a)

{

if(x == T || a == 0) return a;

int flow = 0;

int f;

for(int &i = cur[x]; i < G[x].size(); ++i)

{

Edge &e = edge[G[x][i]];

if(d[x] + 1 == d[e.to] && (f = dfs(e.to, min(a, e.cap- e.flow))) > 0)

{

e.flow += f;

edge[G[x][i] ^ 1].flow -= f;

flow += f;

a -= f;

if(a == 0) break;

}

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

Page 130: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

有上下界的流

}

return flow;

}

inline int dicnic()

{

int ans = 0;

while(bfs())

{

memset(cur,0,sizeof cur);

ans += dfs(S,INF);

}

return ans;

}

int main()

{

int t;

scanf("%d",&t);

while(t--)

{

init();

scanf("%d %d",&n, &m);

scanf("%d %d",&S, &T);

for(int i = 1;i <= m; ++i)

{

int x, y, z;

scanf("%d %d %d",&x, &y,&z);

addedge(x,y,z);

}

int ans = dicnic();

printf("%d\n",ans);

}

return 0;

}

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

/*

* 有上下界的最小(最大)流 * INIT: up[][]为容量上界; low[][]为容量下界;

* CALL: mf = limitflow(n,src,sink); flow[][]为流量分配;

* 另附: 循环流问题 * 描述: 无源无汇的网络N,设N是具有基础有向图D=(V,A)的网络.

*       l和c分别为容量下界和容量上界. 如果定义在A上的函数

*       f满足: f(v, V) = f(V, v). V中任意顶点v,

*       l(a)<=f(a)<=c(a),则称f为网络N的循环流.

* 解法: 添加一个源s和汇t,对于每个下限容量l不为0的边(u, v),

*       将其下限去掉,上限改为c-l,增加两条边(u, t),(s, v),

*       容量均为l.原网络存在循环流等价于新网络最大流是满流.

*/

1

2

3

4

5

6

7

8

9

10

11

12

13

Page 131: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

const int inf = 0x3f3f3f3f;

const int N = 1010;

int up[N][N], low[N][N], flow[N][N];

int pv[N], que[N], d[N];

void maxflow(int n, int src, int sink)

{

   // BFS增广, O(E * maxflow)

   int p, q, t, i, j;

   do

  {

       for (i = 0; i < n; pv[i++] = 0);

       pv[t = src] = src + 1;

       d[t] = inf;

       for (p = q = 0; p <= q && !pv[sink]; t = que[p++])

      {

           for (i = 0; i < n; i++)

          {

               if (!pv[i] && up[t][i] && (j = up[t][i] - flow[t][i]) > 0)

              {

                   pv[que[q++] = i] = +t + 1, d[i] = d[t] < j ? d[t] : j;

              }

               else if (!pv[i] && up[i][t] && (j = flow[i][t]) > 0)

              {

                   pv[que[q++] = i] = -t - 1, d[i] = d[t] < j ? d[t] : j;

              }

          }

      }

       for (i = sink; pv[i] && i != src;)

      {

           if (pv[i] > 0)

          {

               flow[pv[i] - 1][i] += d[sink], i = pv[i] - 1;

          }

           else

          {

               flow[i][-pv[i] - 1] -= d[sink], i = -pv[i] - 1;

          }

      }

  }

   while (pv[sink]);

   return ;

}

int limitflow(int n, int src, int sink)

{

   int i, j, sk, ks;

   if (src == sink)

  {

       return inf;

  }

   up[n][n + 1] = up[n + 1][n] = up[n][n] = up[n + 1][n + 1] = 0;

   for (i = 0; i < n; i++)

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

Page 132: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

最佳边割集

  {

       up[n][i] = up[i][n] = up[n+1][i] = up[i][n+1] = 0;

       for (j = 0; j < n; j++)

      {

           up[i][j] -= low[i][j];

           up[n][i] += low[j][i];

           up[i][n + 1] += low[i][j];

      }

  }

   sk = up[src][sink];

   ks = up[sink][src];

   up[src][sink] = up[sink][src] = inf;

   maxflow(n + 2, n, n + 1);

   for (i = 0; i < n; i++)

  {

       if (flow[n][i] < up[n][i])

      {

           return -1;

      }

  }

   flow[src][sink] = flow[sink][src] = 0;

   up[src][sink] = sk;

   up[sink][src] = ks;     // !min:src<-sink; max:src->sink;

   maxflow(n, sink, src);

   for (i = 0; i < n; i++)

  {

       for (j = 0; j < n; j++)

      {

           up[i][j] += low[i][j];

           flow[i][j] += low[i][j];

      }

  }

   for (j = i = 0; i < n; j += flow[src][i++]);

   return j;

}

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

#define MAXN 100

#define inf 1000000000

int max_flow(int n, int mat[][MAXN], int source, int sink)

{

   int v[MAXN], c[MAXN], p[MAXN], ret = 0, i, j;

   for (;;)

  {

       for (i = 0; i < n; i++)

      {

           v[i] = c[i] = 0;

      }

       for (c[source] = inf; ;)

      {

           for (j = -1, i = 0; i < n; i++)

          {

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

Page 133: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

               if (!v[i] && c[i] && (j == -1 || c[i] > c[j]))

              {

                   j = i;

              }

          }

           if (j < 0)

          {

               return ret;

          }

           if (j == sink)

          {

               break;

          }

           for (v[j] = 1, i = 0; i < n; i++)

          {

               if (mat[j][i] > c[i] && c[j] > c[i])

              {

                   c[i] = mat[j][i] < c[j] ? mat[j][i] : c[j], p[i] = j;

              }

          }

      }

       for (ret += j = c[i = sink]; i != source; i = p[i])

      {

           mat[p[i]][i] -= j, mat[i][p[i]] += j;

      }

  }

}

int best_edge_cut(int n, int mat[][MAXN], int source, int sink, int set[][2], int

&mincost)

{

   int m0[MAXN][MAXN], m[MAXN][MAXN], i, j, k, l, ret = 0, last;

   if (source == sink)

  {

       return -1;

  }

   for (i = 0; i < n; i++)

  {

       for (j = 0; j < n; j++)

      {

           m0[i][j] = mat[i][j];

      }

  }

   for (i = 0; i < n; i++)

  {

       for (j = 0; j < n; j++)

      {

           m[i][j] = m0[i][j];

      }

  }

   mincost = last = max_flow(n, m, source, sink);

   for (k = 0; k < n && last; k++)

  {

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

Page 134: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

最佳点割集

       for (l = 0; l < n && last; l++)

      {

           if (m0[k][l])

          {

               for (i = 0; i < n + n; i++)

              {

                   for (j = 0; j < n + n; j++)

                  {

                       m[i][j] = m0[i][j];

                  }

              }

               m[k][l] = 0;

               if (max_flow(n, m, source, sink) == last - mat[k][l])

              {

                   set[ret][0] = k;

                   set[ret++][1] = l;

                   m0[k][l] = 0;

                   last -= mat[k][l];

              }

          }

      }

  }

   return ret;

}

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

#define MAXN 100

#define inf 1000000000

int max_flow(int n, int mat[][MAXN], int source, int sink)

{

   int v[MAXN], c[MAXN], p[MAXN], ret = 0, i, j;

   for (;;)

  {

       for (i = 0; i < n; i++)

      {

           v[i] = c[i] = 0;

      }

       for (c[source] = inf; ;)

      {

           for (j = -1, i = 0; i < n; i++)

          {

               if (!v[i] && c[i] && (j == -1 || c[i] > c[j]))

              {

                   j = i;

              }

          }

           if (j < 0)

          {

               return ret;

          }

           if (j == sink)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

Page 135: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

          {

               break;

          }

           for (v[j] = 1, i = 0; i < n; i++)

          {

               if (mat[j][i] > c[i] && c[j] > c[i])

              {

                   c[i] = mat[j][i] < c[j] ? mat[j][i] : c[j], p[i] = j;

              }

          }

      }

       for (ret += j = c[i = sink]; i != source; i = p[i])

      {

           mat[p[i]][i] -= j, mat[i][p[i]] += j;

      }

  }

}

int best_vertex_cut(int n, int mat[][MAXN], int *cost, int source, int sink, int

*set, int &mincost)

{

   int m0[MAXN][MAXN], m[MAXN][MAXN], i, j, k, ret = 0, last;

   if (source == sink || mat[source][sink])

  {

       return -1;

  }

   for (i = 0; i < n + n; i++)

  {

       for (j = 0; j < n + n; j++)

      {

           m0[i][j] = 0;

      }

  }

   for (i = 0; i < n; i++)

  {

       for (j = 0; j < n; j++)

      {

           if (mat[i][j])

          {

               m0[i][n + j] = inf;

          }

      }

  }

   for (i = 0; i < n; i++)

  {

       m0[n + i][i] = cost[i];

  }

   for (i = 0; i < n + n; i++)

  {

       for (j = 0; j < n + n; j++)

      {

           m[i][j] = m0[i][j];

      }

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

Page 136: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

最小边割集

  }

   mincost = last = max_flow(n + n, m, source, n + sink);

   for (k = 0; k < n && last; k++)

  {

       if (k != source && k != sink)

      {

           for (i = 0; i < n + n; i++)

          {

               for (j = 0; j < n + n; j++)

              {

                   m[i][j] = m0[i][j];

              }

          }

           m[n + k][k] = 0;

           if (max_flow(n + n, m, source, n + sink) == last - cost[k])

          {

               set[ret++] = k;

               m0[n + k][k] = 0;

               last -= cost[k];

          }

      }

  }

   return ret;

}

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

#define MAXN 100

#define inf 1000000000

int max_flow(int n, int mat[][MAXN], int source, int sink)

{

   int v[MAXN], c[MAXN], p[MAXN], ret = 0, i, j;

   for (;;)

  {

       for (i = 0; i < n; i++)

      {

           v[i] = c[i] = 0;

      }

       for (c[source] = inf; ;)

      {

           for (j = -1, i = 0; i < n; i++)

          {

               if (!v[i] && c[i] && (j == -1 || c[i] > c[j]))

              {

                   j = i;

              }

          }

           if (j < 0)

          {

               return ret;

          }

           if (j == sink)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

Page 137: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

          {

               break;

          }

           for (v[j] = 1, i = 0; i < n; i++)

          {

               if (mat[j][i] > c[i] && c[j] > c[i])

              {

                   c[i] = mat[j][i] < c[j] ? mat[j][i] : c[j], p[i] = j;

              }

          }

      }

       for (ret += j = c[i = sink]; i != source; i = p[i])

      {

           mat[p[i]][i] -= j, mat[i][p[i]] += j;

      }

  }

}

int min_edge_cut(int n, int mat[][MAXN], int source, int sink, int set[][2])

{

   int m0[MAXN][MAXN], m[MAXN][MAXN], i, j, k, l, ret = 0, last;

   if (source == sink)

  {

       return -1;

  }

   for (i = 0; i < n; i++)

  {

       for (j = 0; j < n; j++)

      {

           m0[i][j] = (mat[i][j] != 0);

      }

  }

   for (i = 0; i < n; i++)

  {

       for (j = 0; j < n; j++)

      {

           m[i][j] = m0[i][j];

      }

  }

   last = max_flow(n, m, source, sink);

   for (k = 0; k < n && last; k++)

  {

       for (l = 0; l < n && last; l++)

      {

           if (m0[k][l])

          {

               for (i = 0; i < n + n; i++)

              {

                   for (j = 0; j < n + n; j++)

                  {

                       m[i][j] = m0[i][j];

                  }

              }

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

Page 138: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

最小点割集

               m[k][l] = 0;

               if (max_flow(n, m, source, sink) < last)

              {

                   set[ret][0] = k;

                   set[ret++][1] = l;

                   m0[k][l] = 0;

                   last--;

              }

          }

      }

  }

   return ret;

}

80

81

82

83

84

85

86

87

88

89

90

91

92

/*

* 最小点割集(点连通度)

*/

#define MAXN 100

#define inf 1000000000

int max_flow(int n, int mat[][MAXN], int source, int sink)

{

   int v[MAXN], c[MAXN], p[MAXN], ret = 0, i, j;

   for (; ;)

  {

       for (i = 0; i < n; i++)

      {

           v[i] = c[i] = 0;

      }

       for (c[source] = inf; ;)

      {

           for (j = -1, i = 0; i < n; i++)

          {

               if (!v[i] && c[i] && (j == -1 || c[i] > c[j]))

              {

                   j = i;

              }

          }

           if (j < 0)

          {

               return ret;

          }

           if (j == sink)

          {

               break;

          }

           for (v[j] = 1, i = 0; i < n; i++)

          {

               if (mat[j][i] > c[i] && c[j] > c[i])

              {

                   c[i] = mat[j][i] < c[j] ? mat[j][i] : c[j], p[i] = j;

              }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

Page 139: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

          }

      }

       for (ret += j = c[i = sink]; i != source; i = p[i])

      {

           mat[p[i]][i] -= j, mat[i][p[i]] += j;

      }

  }

}

int min_vertex_cut(int n, int mat[][MAXN], int source, int sink, int *set)

{

   int m0[MAXN][MAXN], m[MAXN][MAXN], i, j, k, ret = 0, last;

   if (source == sink || mat[source][sink])

  {

       return -1;

  }

   for (i = 0; i < n + n; i++)

  {

       for (j = 0; j < n + n; j++)

      {

           m0[i][j] = 0;

      }

  }

   for (i = 0; i < n; i++)

  {

       for (j = 0; j < n; j++)

      {

           if (mat[i][j])

          {

               m0[i][n + j] = inf;

          }

      }

  }

   for (i = 0; i < n; i++)

  {

       m0[n + i][i]=1;

  }

   for (i = 0; i < n + n; i++)

  {

       for (j = 0; j < n + n; j++)

      {

           m[i][j] = m0[i][j];

      }

  }

   last = max_flow(n + n, m, source, n + sink);

   for (k = 0; k < n && last; k++)

  {

       if (k != source && k != sink)

      {

           for (i = 0; i < n + n; i++)

          {

               for (j = 0; j < n + n; j++)

              {

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

Page 140: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

最小覆盖问题

数据结构 左偏树

                   m[i][j] = m0[i][j];

              }

          }

           m[n+k][k] = 0;

           if (max_flow(n + n, m, source, n + sink) < last)

          {

               set[ret++] = k;

               m0[n+k][k] = 0;

               last--;

          }

      }

  }

   return ret;

}

91

92

93

94

95

96

97

98

99

100

101

102

103

104

/*

最小路径覆盖

最小路径覆盖O(n^3)路径覆盖:就是在图中找一些路经,使之覆盖了图中的所有顶点,且任何一个顶点有且只有一条路径与之关联。最小路径覆盖:就是找出最少的路径条数,使之成为P的一个路径覆盖。路径覆盖与二分图匹配的关系:最小路径覆盖=|P|-最大匹配数;其中最大匹配数的求法是把P中的每个顶点pi分成两个顶点pi’与pi”,如果在p中存在一条pi到pj的边,那么在二分图P’中就有一条连接pi’与pj”的有向边(求二分图匹配时必须是单向边);这里pi’就是p中pi的出边,pj”就是p中pj的一条入边;

有向图: 最小路径覆盖=|P|-最大匹配数;

无向图: 最小路径覆盖=|P|-最大匹配数/2;

最小点集覆盖

结论:一个二分图中的最大匹配数等于这个图中的最小点覆盖数。*/

1

2

3

4

5

6

7

8

9

10

11

12

/*

* 合并复杂度 O(log N)

* INIT: init()读入数据并进行初始化;

* CALL: merge() 合并两棵左偏树;

*       ins() 插入一个新节点;

*       top() 取得最小结点;

*       pop() 取得并删除最小结点;

*       del() 删除某结点;

*       add() 增/减一个结点的键值;

*       iroot() 获取结点i的根;

*/

#define typec int       // type of key val

const int na = -1;

const int N = 1010;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

Page 141: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

struct node

{

   typec key;

   int l, r, f, dist;

} tr[N];

int iroot(int i)

{   // find i's root

   if (i == na)

  {

       return i;

  }

   while (tr[i].f != na)

  {

       i = tr[i].f;

  }

   return i;

}

int merge(int rx, int ry)

{

   // two root:   rx, ry

   if (rx == na)

  {

       return ry;

  }

   if (ry == na)

  {

       return rx;

  }

   if (tr[rx].key > tr[ry].key)

  {

       swap(rx, ry);

  }

   int r = merge(tr[rx].r, ry);

   tr[rx].r = r;

   tr[r].f = rx;

   if (tr[r].dist > tr[tr[rx].l].dist)

  {

       swap(tr[rx].l, tr[rx].r);

  }

   if (tr[rx].r == na)

  {

       tr[rx].dist = 0;

  }

   else

  {

       tr[rx].dist = tr[tr[rx].r].dist + 1;

  }

   return rx;  // return new root

}

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

Page 142: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

int ins(int i, typec key, int root)

{   // add a new node(i, key)

   tr[i].key = key;

   tr[i].l = tr[i].r = tr[i].f = na;

   tr[i].dist = 0;

   return root = merge(root, i);   // return new root

}

int del(int i)

{   // delete node i

   if (i == na)

  {

       return i;

  }

   int x, y, l, r;

   l = tr[i].l;

   r = tr[i].r;

   y = tr[i].f;

   tr[i].l = tr[i].r = tr[i].f = na;

   tr[x = merge(l, r)].f = y;

   if (y != na && tr[y].l == i)

  {

       tr[y].l = x;

  }

   if (y != na && tr[y].r == i)

  {

       tr[y].r = x;

  }

   for (; y != na; x = y, y = tr[y].f)

  {

       if (tr[tr[y].l].dist < tr[tr[y].r].dist)

      {

           swap(tr[y].l, tr[y].r);

      }

       if (tr[tr[y].r].dist + 1 == tr[y].dist)

      {

           break;

      }

       tr[y].dist = tr[tr[y].r].dist + 1;

  }

   if (x != na)    // return new root

  {

       return iroot(x);

  }

   else return iroot(y);

}

node top(int root)

{

   return tr[root];

}

node pop(int &root)

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

Page 143: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

线段树扫描线

 

{

   node out = tr[root];

   int l = tr[root].l, r = tr[root].r;

   tr[root].l = tr[root].r = tr[root].f = na;

   tr[l].f = tr[r].f = na;

   root = merge(l, r);

   return out;

}

int add(int i, typec val)   // tr[i].key += val

{

   if (i == na)

  {

       return i;

  }

   if (tr[i].l == na && tr[i].r == na && tr[i].f == na)

  {

       tr[i].key += val;

       return i;

  }

   typec key = tr[i].key + val;

   int rt = del(i);

   return ins(i, key, rt);

}

void init(int n)

{

   for (int i = 1; i <= n; i++)

  {

       scanf("%d", &tr[i].key);    // %d: type of key

       tr[i].l = tr[i].r = tr[i].f = na;

       tr[i].dist = 0;

  }

   return ;

}

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

/*

求矩形并的面积(线段树+离散化+扫描线)

参考题目链接:POJ 1151 Atlantis

Each test case starts with a line containing a single integer n (1 <= n <= 100) of

available maps.

The n following lines describe one map each.

Each of these lines contains four numbers x1、y1、x2、y2 (0 <= x1 < x2 <= 100000; 0

<= y1 < y2 <= 100000), not necessarily integers.

The values (x1, y1) and (x2,y2) are the coordinates of the

top-left resp.

Bottom-Right corner of the mapped area.

1

2

3

4

5

6

7

8

9

10

11

Page 144: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

*/

/*

* 本题中的坐标是浮点类型的, 故不能将坐标直接离散.我们必须为它们建立一个对应关系,

* 用一个整数去对应一个浮点数这样的对应关系在本题的数组y[]中。 */

struct node

{

   int st, ed, c;      // c: 区间被覆盖的层数, m: 区间的测度    double m;

} ST[802];

struct line

{

   double x, y1, y2;   // 纵方向直线, x:直线横坐标, y1 y2:直线上的下面与上面的两个纵坐标    bool s;             // s = 1 : 直线为矩形的左边, s = 0:直线为矩形的右边} Line[205];

double y[205], ty[205]; // y[]整数与浮点数的对应数组; ty[]:用来求y[]的辅助数组

void build(int root, int st, int ed)

{

   ST[root].st = st;

   ST[root].ed = ed;

   ST[root].c = 0;

   ST[root].m = 0;

   if (ed - st > 1)

  {

       int mid = (st + ed) / 2;

       build(root * 2, st, mid);

       build(root * 2 + 1, mid, ed);

  }

   return ;

}

void updata(int root)

{

   if (ST[root].c > 0)

  {   // 将线段树上区间的端点分别映射到y[]数组所对应的浮点数上,由此计算出测度        ST[root].m = y[ST[root].ed - 1] - y[ST[root].st - 1];

  }

   else if (ST[root].ed - ST[root].st == 1)

  {

       ST[root].m = 0;

  }

   else

  {

       ST[root].m = ST[root * 2].m + ST[root * 2 + 1].m;

  }

   return ;

}

void insert(int root, int st, int ed)

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

Page 145: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

{

   if (st <= ST[root].st && ST[root].ed <= ed)

  {

       ST[root].c++;

       updata(root);

       return ;

  }

   if (ST[root].ed - ST[root].st == 1)

  {

       return ;    // 不出错的话 这句话就是冗余的   }

   int mid = (ST[root].ed + ST[root].st) / 2;

   if (st < mid)

  {

       insert(root * 2, st, ed);

  }

   if (ed > mid)

  {

       insert(root * 2 + 1, st, ed);

  }

   updata(root);

   return ;

}

void Delete(int root, int st, int ed)

{

   if (st <= ST[root].st && ST[root].ed <= ed)

  {

       ST[root].c--;

       updata(root);

       return ;

  }

   if (ST[root].ed - ST[root].st == 1)

  {

       return ;    // 不出错的话 这句话就是冗余的   }

   int mid = (ST[root].st + ST[root].ed) / 2;

   if (st < mid)

  {

       Delete(root * 2, st, ed);

  }

   if (ed > mid)

  {

       Delete(root * 2 + 1, st, ed);

  }

   updata(root);

   return ;

}

int Correspond(int n, double t)

{

   // 二分查找出浮点数t在数组y[]中的位置(此即所谓的映射关系)

   int low, high, mid;

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

Page 146: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

   low = 0;

   high = n - 1;

   while (low < high)

  {

       mid = (low + high) / 2;

       if (t > y[mid])

      {

           low = mid + 1;

      }

       else

      {

           high = mid;

      }

  }

   return high + 1;

}

bool cmp(line l1, line l2)

{

   return l1.x < l2.x;

}

int main()

{

   int n, i, num, l, r, c = 0;

   double area, x1, x2, y1, y2;

   while (cin >> n, n)

  {

       for (i = 0; i < n; i++)

      {

           cin >> x1 >> y1 >> x2 >> y2;

           Line[2 * i].x = x1;

           Line[2 * i].y1 = y1;

           Line[2 * i].y2 = y2;

           Line[2 * i].s = 1;

           Line[2 * i + 1].x = x2;

           Line[2 * i + 1].y1 = y1;

           Line[2 * i + 1].y2 = y2;

           Line[2 * i + 1].s = 0;

           ty[2 * i] = y1;

           ty[2 * i + 1] = y2;

      }

       n <<= 1;

       sort(Line, Line + n, cmp);

       sort(ty, ty + n);

       y[0] = ty[0];

       // 处理数组ty[]使之不含重覆元素,得到新的数组存放到数组y[]中        for (i = num = 1; i < n; i++)

      {

           if (ty[i] != ty[i - 1])

          {

               y[num++] = ty[i];

          }

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

Page 147: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

      }

       build(1, 1, num);   // 树的叶子节点与数组y[]中的元素个数相同,以便建立一一对应的关系        area = 0;

       for (i = 0; i < n - 1; i++)

      {   // 由对应关系计算出线段两端在树中的位置            l = Correspond(num, Line[i].y1);

           r = Correspond(num, Line[i].y2);

           if (Line[i].s)  // 插入矩形的左边           {

               insert(1, l, r);

          }

           else            // 删除矩形的右边           {

               Delete(1, l, r);

          }

           area += ST[1].m * (Line[i + 1].x - Line[i].x);

      }

       cout << "Test case #" << ++c << endl << "Total explored area: ";

       cout << fixed << setprecision(2) << area << endl << endl;   // 需要引入iomanip头文件   }

   return 0;

}

/*求矩形并的周长(线段树+离散化+扫描线)

参考题目链接:POJ 1177 Picture

The first line contains the number of rectangles pasted on the wall.

In each of the subsequent lines, one can find the integer coordinates of the lower

left vertex and the upper right vertex of each rectangle.

The values of those coordinates are given as ordered pairs consisting of an x-

coordinate followed by a y-coordinate. 0 <= number of rectangles < 5000.

All coordinates are in the range [-10000,10000] and any existing rectangle has a

positive area.

*/

struct node

{

   int st, ed, m, lbd, rbd;

   int sequence_line, count;

} ST[40005];

void build(int st, int ed, int v)       // 建树,区间为[st, ed]

{

   ST[v].st = st;

   ST[v].ed = ed;

   ST[v].m = ST[v].lbd = ST[v].rbd = 0;

   ST[v].sequence_line = ST[v].count = 0;

   if (ed - st > 1)

  {

       int mid = (st + ed) / 2;

       build(st, mid, 2 * v + 1);

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

Page 148: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       build(mid, ed, 2 * v + 2);

  }

   return ;

}

void UpData(int v)                      // 更新结点区间的测度{

   if (ST[v].count > 0)

  {

       ST[v].m = ST[v].ed - ST[v].st;

       ST[v].lbd = ST[v].rbd = 1;

       ST[v].sequence_line = 1;

       return ;

  }

   if (ST[v].ed - ST[v].st == 1)

  {

       ST[v].m = 0;

       ST[v].lbd = ST[v].rbd = 0;

       ST[v].sequence_line = 0;

  }

   else

  {

       int left = 2 * v + 1, right = 2 * v + 2;

       ST[v].m = ST[left].m + ST[right].m;

       ST[v].sequence_line = ST[left].sequence_line + ST[right].sequence_line -

(ST[left].rbd & ST[right].lbd);

       ST[v].lbd = ST[left].lbd;

       ST[v].rbd = ST[right].rbd;

  }

   return ;

}

void insert(int st, int ed, int v)

{

   if (st <= ST[v].st && ed >= ST[v].ed)

  {

       ST[v].count++;

       UpData(v);

       return ;

  }

   int mid = (ST[v].st + ST[v].ed) / 2;

   if (st < mid)

  {

       insert(st, ed, 2 * v + 1);

  }

   if (ed > mid)

  {

       insert(st, ed, 2 * v + 2);

  }

   UpData(v);

   return ;

}

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

Page 149: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

void Delete(int st, int ed, int v)

{

   if (st <= ST[v].st && ed >= ST[v].ed)

  {

       ST[v].count--;

       UpData(v);

       return ;

  }

   int mid = (ST[v].st + ST[v].ed) / 2;

   if (st < mid)

  {

       Delete(st, ed, 2 * v + 1);

  }

   if (ed > mid)

  {

       Delete(st, ed, 2 * v + 2);

  }

   UpData(v);

   return ;

}

struct line

{

   int x, y1, y2;  // y1 < y2

   bool d;         // d=true表示该线段为矩形左边,d=false表示该线段为矩形的右边} a[10003];

bool cmp(line t1, line t2)  // 为线段排序的函数,方便从左向右的扫描{

   return t1.x < t2.x;

}

void cal_C(int n);

int main()

{

   int n, x1, x2, y1, y2, i, j, suby, upy;

   while (scanf("%d",&n) != EOF)

  {

       j = 0;

       suby = 10000;

       upy = -10000;

       for (i = 0; i < n; i++)

      {

           scanf("%d%d%d%d", &x1, &y1, &x2, &y2);

           a[j].x = x1;

           a[j].y1 = y1;

           a[j].y2 = y2;

           a[j].d = 1;

           j++;

           a[j].x = x2;

           a[j].y1 = y1;

           a[j].y2 = y2;

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

Page 150: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

线段树位运算解决染色问题

           a[j].d = 0;

           j++;

           if (suby > y1)

          {

               suby = y1;

          }

           if (upy < y2)

          {

               upy = y2;

          }

      }

       sort(a, a + j, cmp);

       build(suby, upy, 0);

       cal_C(j);

  }

   return 0;

}

void cal_C(int n)

{

   int i, t2, sum = 0;

   t2 = 0;

   a[n] = a[n - 1];

   for (i = 0; i < n; i++)

  {

       if (a[i].d == 1)

      {

           insert(a[i].y1, a[i].y2, 0);

      }

       else

      {

           Delete(a[i].y1, a[i].y2, 0);

      }

       sum += ST[0].sequence_line * (a[i + 1].x - a[i].x) * 2;

       sum += abs(ST[0].m - t2);

       t2 = ST[0].m;

  }

   printf("%d\n", sum);

}

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

//线段树 位运算 染色

#include <bits/stdc++.h>

using namespace std;

#define N 100010

typedef bitset <32> B32;

struct node

{

int l, r;

1

2

3

4

5

6

7

8

9

10

11

Page 151: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

B32 v, lazy;

inline node() {}

inline node(int l, int r, B32 v, B32 lazy) : l(l), r(r), v(v), lazy(lazy) {}

}tree[N << 2];    

inline void pushup(int id)

{

tree[id].v = tree[id << 1].v | tree[id << 1 | 1].v;

}

inline void maintain(int id)    

{

if (tree[id].l >= tree[id].r) return;  

if (tree[id].lazy.count())  

{

B32 lazy = tree[id].lazy; tree[id].lazy = 0;  

tree[id << 1].v = tree[id << 1].lazy = lazy;  

tree[id << 1 | 1].v = tree[id << 1 | 1].lazy = lazy;

}

}

inline void build(int id, int l, int r)

{

tree[id] = node(l, r, 0, 0);

if (l == r)

{

tree[id].v[1] = 1;

return;

}

int mid = (l + r) >> 1;

build(id << 1, l, mid);

build(id << 1 | 1, mid + 1, r);

pushup(id);  

}

inline void update(int id, int l, int r, B32 val)  

{

if (tree[id].l >= l && tree[id].r <= r)

{

tree[id].v = val;

tree[id].lazy = val;

return;

}

maintain(id);  

int mid = (tree[id].l + tree[id].r) >> 1;

if (l <= mid) update(id << 1, l, min(r, mid), val);

if (r > mid) update(id << 1 | 1, max(l, mid + 1), r, val);

pushup(id);

}

B32 anssum;

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

Page 152: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

线段树动态开点

inline void query(int id, int l, int r)  

{

if (tree[id].l >= l && tree[id].r <= r)

{

anssum |= tree[id].v;  

return;

}

maintain(id);  

int mid = (tree[id].l + tree[id].r) >> 1;

if (l <= mid) query(id << 1, l, min(r, mid));

if (r > mid) query(id << 1 | 1, max(l, mid + 1), r);  

pushup(id);  

}

int main()

{

#ifdef LOCAL

freopen("Test.in", "r", stdin);

#endif

int L, T, O;

while (scanf("%d%d%d", &L, &T, &O) != EOF)  

{

build(1, 1, L);

char op; int a, b, c;

while (O--)

{

scanf(" %c", &op);

if (op == 'C')

{

scanf("%d%d%d", &a, &b, &c);

if (a > b) swap(a, b);

update(1, a, b, 1 << c);  

}

else

{

scanf("%d%d", &a, &b);

if (a > b) swap(a, b);  

anssum = 0;

query(1, a, b);

printf("%d\n", anssum.count());

}

}

}

}

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

// 单点维护

#include <bits/stdc++.h>

using namespace std;

#define INF 0x3f3f3f3f

1

2

3

4

5

6

Page 153: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

#define N 1000100

struct node

{

int l, r, v;

inline node()

{

l = 0, r = 0, v = INF;

}

inline node(int l, int r, int v) : l(l), r(r), v(v) {}

}tree[N << 2];

int root[55];

int cnt, tag;

inline void Init()

{

for (int i = 0; i <= cnt; ++i)

tree[i] = node();

memset(root, 0, sizeof root);

cnt = 0;

}

inline void update(int &id, int l, int r, int x, int y)

{

if (id == 0)

{

id = ++cnt;

tree[id].v = x;

}

tree[id].v = min(tree[id].v, x);

if (l == r) return;

int mid = (l + r) >> 1;

if (y <= mid) update(tree[id].l, l, mid, x, y);

else update(tree[id].r, mid + 1, r, x, y);

}

inline void query(int id, int l, int r, int ql, int qr, int x)

{

if (id == 0 || tag) return;

if (l >= ql && r <= qr)

{

if (tree[id].v <= x)

tag = 1;

return;

}

int mid = (l + r) >> 1;

if (ql <= mid) query(tree[id].l, l, mid, ql, min(mid, qr), x);

if (qr > mid) query(tree[id].r, mid + 1, r, max(ql, mid + 1), qr, x);

}

int main()

{

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

Page 154: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

int op, x, y1, y2, c;

while (scanf("%d", &op) != EOF)

{

if (op == 3) return 0;

if (op == 0)

{

Init();

}

if (op == 1)

{

scanf("%d%d%d", &x, &y1, &c);

update(root[c], 1, 1000000, x, y1);

}

if (op == 2)

{

scanf("%d%d%d", &x, &y1, &y2);

if (y1 > y2) swap(y1, y2);

int ans = 0;

for (int i = 0; i <= 50; ++i)

{

tag = 0;

query(root[i], 1, 1000000, y1, y2, x);

if (tag)

{

ans++;

}

}

printf("%d\n", ans);

}

}

return 0;

}

//区间维护

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <iostream>

using namespace std;

#define N 2000100

struct node

{

int l, r, v, lazy;

inline node()

{

l = 0, r = 0, v = 0, lazy = -1;

}

inline node(int l, int r, int v, int lazy) : l(l), r(r), v(v), lazy(lazy) {}

}tree[N << 1];  

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

Page 155: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

int root[40], L[N], R[N], pos;  

inline void Init()

{

for (int i = 0; i <= pos; ++i)

tree[i] = node();

memset(root, 0, sizeof root);

memset(L, 0, sizeof L);

memset(R, 0, sizeof R);

pos = 0;  

}

inline void pushup(int id)

{

int l = L[id], r = R[id];

tree[id].v = tree[l].v + tree[r].v;

}

inline void maintain(int id)  

{

if (tree[id].l >= tree[id].r) return;

if (tree[id].lazy != -1)

{

int lazy = tree[id].lazy; tree[id].lazy = -1;

int l = tree[id].l, r = tree[id].r;  

int mid = (l + r) >> 1;

if (L[id] == 0)

L[id] = ++pos;

tree[L[id]] = node(l, mid, (mid - l + 1) * lazy, lazy);

if (R[id] == 0)

R[id] = ++pos;

tree[R[id]] = node(mid + 1, r, (r - mid) * lazy, lazy);

}

}

inline void update(int &id, int l, int r, int ql, int qr, int val)  

{

if (id == 0)

{

id = ++pos;

tree[id] = node(l, r, 0, -1);

}

if (tree[id].l >= ql && tree[id].r <= qr)  

{

tree[id].v = (r - l + 1) * val;

tree[id].lazy = val;  

return;

}

maintain(id);

int mid = (l + r) >> 1;

if (ql <= mid) update(L[id], l, mid, ql, min(qr, mid), val);

if (qr > mid) update(R[id], mid + 1, r, max(ql, mid + 1), qr, val);

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

Page 156: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

pushup(id);

}

int anssum;

inline void query(int &id, int l, int r)  

{

if (id == 0) return;

if (tree[id].l >= l && tree[id].r <= r)

{

anssum += tree[id].v;

return;

}

maintain(id);  

int mid = (tree[id].l + tree[id].r) >> 1;

if (l <= mid) query(L[id], l, min(r, mid));

if (r > mid) query(R[id], max(mid + 1, l), r);  

pushup(id);  

}

int main()

{

int L, T, O;

while (scanf("%d%d%d", &L, &T, &O) != EOF)  

{

Init();

update(root[1], 1, L, 1, L, 1);  

char op; int a, b, c;

while (O--)

{

scanf(" %c", &op);

if (op == 'C')

{

scanf("%d%d%d", &a, &b, &c);

if (a > b) swap(a, b);

for (int i = 1; i <= T; ++i)  

update(root[i], 1, L, a, b, 0);

update(root[c], 1, L, a, b, 1);  

}

else

{

scanf("%d%d", &a, &b);

if (a > b) swap(a, b);  

int ans = 0;

for (int i = 1; i <= T; ++i)

{

anssum = 0;

query(root[i], a, b);  

if (anssum) ++ans;

}

printf("%d\n", ans);

}

}

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

Page 157: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

可持久化线段树

}

}

219

220

/*

下面的程序实现了一个维护区间和的可持久化线段树,支持区间修改。而且这个程序包含了一个demo。首先输入一个n,随后输入n个整数,表示a[1]~a[n]的初始值。随后开始查询和修改操作,输入q查询,m修改。查询接受一个版本号(从0开始),输出序列所有的值。修改接受u、v和w,表示将区间[u,v]每个元素加上w。*/

struct node

{

int lch, rch, pre;

int add, sum;

inline node() {}

inline node(int lch, int rch, int pre, int add, int sum) : lch(lch), rch(rch),

pre(pre), add(add), sum(sum) {}

}tree[(maxn << 2) << 2];

int pos, curver;

int a[maxn], rt[maxn];

inline void Init()

{

pos = -1; curver = 0;

}

inline int createIndentity(int id)

{

++pos;

tree[pos] = node(-1, -1, id, tree[id].add, tree[id].sum);

return pos;

}

inline void pushup(int id)

{

int lch = tree[id].lch, rch = tree[id].rch;

tree[id].sum = tree[lch].sum + tree[rch].sum;

}

inline void pushdown(int id, int l, int r, int mid)

{

int lch = tree[id].lch, rch = tree[id].rch;

if (lch == -1 || rch == -1)

{

int pre = tree[id].pre;

lch = tree[id].lch = createIndentity(tree[pre].lch);

rch = tree[id].rch = createIndentity(tree[pre].rch);

}

int add = tree[id].add; tree[id].add = 0;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

Page 158: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

tree[lch].add += add; tree[rch].add += add;

tree[lch].sum += add * (mid - l + 1);

tree[rch].sum += add * (r - mid);

}

inline int build(int l, int r)

{

int poss = ++pos;

tree[poss] = node(-1, -1, -1, 0, 0);

if (l == r)

{

tree[pos].sum = a[l];

return poss;

}

int mid = (l + r) >> 1;

tree[poss].lch = build(l, mid);

tree[poss].rch = build(mid + 1, r);

pushup(poss);

return poss;

}

inline int update(int id, int l, int r, int x, int y, int z)

{

int poss = ++pos;

tree[poss] = node(-1, -1, id, tree[id].add, tree[id].sum);

if (x <= l && r <= y)

{

tree[poss].add = tree[id].add + z;

tree[poss].sum = tree[id].sum + (r - l + 1) * z;

return pos;

}

int mid = (l + r) >> 1;

if (tree[id].add) pushdown(id, l, r, mid);

if (x <= mid) tree[poss].lch = update(tree[id].lch, l, mid, x, y, z);

else tree[poss].lch = tree[id].lch;

if (mid < y) tree[poss].rch = update(tree[id].rch, mid + 1, r, x, y, z);

else tree[poss].rch = tree[id].rch;

pushup(poss);

return poss;

}

inline int query(int id, int l, int r, int x, int y)

{

if (x <= l && r <= y) return tree[id].sum;

int mid = (l + r) >> 1, sum = 0;

if (tree[id].add) pushdown(id, l, r, mid);

if (x <= mid) sum += query(tree[id].lch, l, mid, x, y);

if (mid < y) sum += query(tree[id].rch, mid + 1, r, x, y);

pushup(id);

return sum;

}

int n;

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

Page 159: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

int main()

{

scanf("%d", &n); Init();

for (int i = 1; i <= n; i++) scanf("%d", a + i);

rt[curver] = build(1, n);

while (true)

{

int u, v, w;

char op[3];

scanf("%s", op);

if (op[0] == 'm')

{

scanf("%d%d%d", &u, &v, &w);

rt[curver + 1] = update(rt[curver], 1, n, u, v, w);

++curver;

for (int i = 1; i <= n; i++) printf("%d%c", query(rt[curver], 1, n, i,

i), " \n"[i == n]);

}

else

{

scanf("%d", &w);

for (int i = 1; i <= n; ++i) printf("%d%c", query(rt[w], 1, n, i, i),

" \n"[i == n]);

}

}

}

/*

不用pushdown 省内存 我们用一个标记记录当前区间的累加和,查询时从根节点走到目标节点的过程中不断累加所经过节点的标记值*/

#include <bits/stdc++.h>

using namespace std;

#define N 100010

#define M N * 40

#define ll long long

int n, q;

int arr[N], rt[N], tot;

struct node

{

int lch, rch, pre;

ll lazy, sum;

inline node() {}

inline node(int lch, int rch, int pre, ll lazy, ll sum) : lch(lch), rch(rch),

pre(pre), lazy(lazy), sum(sum) {}  

}tree[M];

inline void pushup(int id)

{

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

Page 160: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

tree[id].sum = tree[tree[id].lch].sum + tree[tree[id].rch].sum;

}

inline int build(int l, int r)

{

int poss = ++tot;

tree[poss] = node(-1, -1, -1, 0, 0);

if (l == r)

{

tree[poss].sum = arr[l];

return poss;

}

int mid = (l + r) >> 1;  

tree[poss].lch = build(l, mid);

tree[poss].rch = build(mid + 1, r);

pushup(poss);

return poss;

}

inline int update(int id, int l, int r, int ql, int qr, ll val)

{

int poss = ++tot;

tree[poss] = node(tree[id].lch, tree[id].rch, id, tree[id].lazy, tree[id].sum

+ val * (qr - ql + 1));

if (l == ql && r == qr)

{

tree[poss].lazy += val;  

return poss;  

}

int mid = (l + r) >> 1;

if (ql <= mid) tree[poss].lch = update(tree[id].lch, l, mid, ql, min(qr, mid),

val);

if (qr > mid) tree[poss].rch = update(tree[id].rch, mid + 1, r, max(ql, mid +

1), qr, val);

return poss;

}

ll anssum;

inline void query(int id, int l, int r, int ql, int qr)

{

if (l == ql && r == qr)

{

anssum += tree[id].sum;

return;

}

anssum += tree[id].lazy * (qr - ql + 1);

int mid = (l + r) >> 1;

if (ql <= mid) query(tree[id].lch, l, mid, ql, min(qr, mid));

if (qr > mid) query(tree[id].rch, mid + 1, r, max(ql, mid + 1), qr);

}

inline void Run()

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

Page 161: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

动态开点主席树

{

while (scanf("%d%d", &n, &q) != EOF)

{

for (int i = 1; i <= n; ++i) scanf("%d", arr + i); tot = -1;

char op; int l, r, t; ll d; rt[0] = build(1, n); int cnt = 0;

for (int i = 1; i <= q; ++i)

{

scanf(" %c", &op);

if (op == 'C')

{

scanf("%d%d%lld", &l, &r, &d);

rt[cnt + 1] = update(rt[cnt], 1, n, l, r, d);  

++cnt;

}

else if (op == 'Q')

{

scanf("%d%d", &l, &r);

anssum = 0; query(rt[cnt], 1, n, l, r);

printf("%lld\n", anssum);

}

else if (op == 'H')

{

scanf("%d%d%d", &l, &r, &t);

anssum = 0; query(rt[t], 1, n, l, r);

printf("%lld\n", anssum);

}

else

{

scanf("%d", &t);

cnt = t;

tot = rt[cnt + 1];

}

}

}

}

int main()

{

#ifdef LOCAL

freopen("Test.in", "r", stdin);

#endif

Run();

return 0;

}

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

//动态开点主席树

#include <bits/stdc++.h>

using namespace std;

1

2

3

4

Page 162: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

#define N 100010

#define M N * 100

#define D 1000000000

int q;

unordered_map <string, int> mp;

int rt[N], wt[N], L[M], R[M], C[M], tot, cnt;

inline void Init()

{

mp.clear(); tot = 0; cnt = 0;

rt[0] = wt[0] = 0; L[0] = R[0] = C[0] = 0;

}

inline int ID(string s)

{

if (mp.find(s) != mp.end()) return mp[s];

return mp[s] = ++cnt;

}

inline void pushup(int now, int pre, int val)

{

L[now] = L[pre];

R[now] = R[pre];

C[now] = C[pre] + val;

}

inline void update(int &now, int pre, int l, int r, int pos, int val)

{

now = ++tot; pushup(now, pre, val);

if (l == r) return;

int mid = (l + r) >> 1;

if (pos <= mid) update(L[now], L[pre], l, mid, pos, val);

else update(R[now], R[pre], mid + 1, r, pos, val);

}

inline int query(int root, int l, int r, int ql, int qr)

{

if (root == 0) return 0;

if (l >= ql && r <= qr) return C[root];

int mid = (l + r) >> 1;

int sum = 0;

if (ql <= mid) sum += query(L[root], l, mid, ql, qr);

if (qr > mid) sum += query(R[root], mid + 1, r, ql, qr);

return sum;

}

inline void Run()

{

cin.tie(0);

cout.tie(0);

ios::sync_with_stdio(false);

string op, name; int v;

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

Page 163: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

while (cin >> q)

{

Init();

for (int i = 1; i <= q; ++i)

{

rt[i] = rt[i - 1]; wt[i] = wt[i - 1];

cin >> op;

if (op == "set")

{

cin >> name >> v;

int id = ID(name);

int p = query(wt[i], 1, D, id, id);

if (p) update(rt[i], rt[i], 1, D, p, -1);

update(rt[i], rt[i], 1, D, v, 1);

update(wt[i], wt[i], 1, D, id, v - p);

}

else if (op == "remove")

{

cin >> name;

int id = ID(name);

int p = query(wt[i], 1, D, id, id);

if (p)

{

update(rt[i], rt[i], 1, D, p, -1);

update(wt[i], wt[i], 1, D, id, -p);

}

}

else if (op == "query")

{

cin >> name;

int id = ID(name);

int p = query(wt[i], 1, D, id, id);

if (!p) cout << -1 << "\n";

else

cout << query(rt[i], 1, D, 1, p - 1) << "\n";

cout << flush;

}

else

{

cin >> v;

rt[i] = rt[i - v - 1];

wt[i] = wt[i - v - 1];

}

}

}

}

int main()

{

#ifdef LOCAL

freopen("Test.in", "r", stdin);

#endif

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

Page 164: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

 

线段树找区间内第一个大于某个数的数

Run();

return 0;

}

111

112

113

114

115

116

117

//线段树找区间内第一个大于某个数的数

inline int querymin(int id, int l, int r, ll val)  

{

if (l > r) return INF;  

if (tree[id].l == tree[id].r) return tree[id].Max > val ? tree[id].l : INF;  

pushdown(id);  

int pos = INF;

int mid = (tree[id].l + tree[id].r) >> 1;

if (r <= mid)

{

if (tree[id << 1].Max > val) pos = querymin(id << 1, l, r, val);

}

else if (l > mid)

{

if (tree[id << 1 | 1].Max > val) pos = querymin(id << 1 | 1, l, r, val);

}

else

{

if (tree[id << 1].Max > val)  pos = min(pos, querymin(id << 1, l, mid,

val));

if (pos == INF && tree[id << 1 | 1].Max > val) pos = min(pos, querymin(id

<< 1 | 1, mid + 1, r, val));

}

pushup(id);  

return pos;  

}

//线段树找区间内有多少个比某个数大的数

inline int query(int id, int l, int r, int Max)

{

if (l > r) return 0;

if (tree[id].Max < Max) return min(tree[id].r, r) - max(tree[id].l, l) + 1;  

int mid = (tree[id].l + tree[id].r) >> 1;

int res = 0;

if (l <= mid && tree[id << 1].Min < Max) res += query(id << 1, l, r, Max);

if (r > mid && tree[id << 1 | 1].Min < Max) res += query(id << 1 | 1, l, r,

Max);

return res;  

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

Page 165: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

动态维护最长上升子序列

#include <bits/stdc++.h>

using namespace std;

#define N 100010

int n, q;

struct node

{

int l, r, cnt;

double Max;

inline node() {}

inline node(int _l, int _r)

{

l = _l, r = _r;

cnt = 0, Max = 0;

}

}tree[N << 2];

inline void build(int id, int l, int r)

{

tree[id] = node(l, r);  

if (l == r) return;

int mid = (l + r) >> 1;

build(id << 1, l, mid);

build(id << 1 | 1, mid + 1, r);

}

inline int query(int id, double v)

{

if (tree[id].l == tree[id].r) return tree[id].Max > v;

int mid = (tree[id].l + tree[id].r) >> 1;

if (tree[id].Max <= v) return 0;

if (tree[id << 1].Max <= v) return query(id << 1 | 1, v);

else return tree[id].cnt - tree[id << 1].cnt + query(id << 1, v);  

}

inline void update(int id, int x, double val)

{

if (tree[id].l == tree[id].r)

{

tree[id].cnt = 1;

tree[id].Max = val;

return;

}

int mid = (tree[id].l + tree[id].r) >> 1;

if (x <= mid) update(id << 1, x, val);

else update(id << 1 | 1, x, val);  

tree[id].cnt = tree[id << 1].cnt + query(id << 1 | 1, tree[id << 1].Max);

tree[id].Max = max(tree[id << 1].Max, tree[id << 1 | 1].Max);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

Page 166: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

并查集

inline void Run()

{

while (scanf("%d%d", &n, &q) != EOF)

{

build(1, 1, n);

for (int i = 1, x, y; i <= q; ++i)

{

scanf("%d%d", &x, &y);

double tmp = y * 1.0 / x;

update(1, x, tmp);

printf("%d\n", tree[1].cnt);

}

}

}

int main()

{

#ifdef LOCAL

freopen("Test.in", "r", stdin);

#endif

Run();  

return 0;

}

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

//递归版本 自带路径压缩 比不递归更快

int find(int x)

{

if (x != pre[x])

  pre[x] = find(pre[x]);

   return pre[x];

}

void join(int x, int y)

{

int fx = find(x), fy = find(y);

if (fx != fy)

{

pre[fx] = fy;

tot[fy] += tot[fx]; // 可以记录连通块里面的元素个数

}

}

//并查集树上缩点

#include <bits/stdc++.h>

using namespace std;

#define N 10010

struct Edge

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

Page 167: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

{

int to, nx;

inline Edge() {}

inline Edge(int to, int nx) : to(to), nx(nx) {}

}edge[N << 1];

int n, m, a, b, x, y, ans;

int head[N], pos, sz[N];

int rmq[N << 1], F[N << 1], P[N], fa[N], deep[N], cnt;

int pre[N];

struct ST

{

int mm[N << 1];

int dp[N << 1][20];

inline void init(int n)

{

mm[0] = -1;

for (int i = 1; i <= n; ++i)

{

mm[i] = ((i & (i - 1)) == 0) ? mm[i - 1] + 1 : mm[i - 1];

dp[i][0] = i;

}

for (int j = 1; j <= mm[n]; ++j)

{

for (int i = 1; i + (1 << j) - 1 <= n; ++i)

{

dp[i][j] = rmq[dp[i][j - 1]] < rmq[dp[i + (1 << (j - 1))][j - 1]]

? dp[i][j - 1] : dp[i + (1 << (j - 1))][j - 1];

}

}

}

inline int query(int a, int b)

{

if (a > b) swap(a, b);

int k = mm[b - a + 1];

return rmq[dp[a][k]] <= rmq[dp[b - (1 << k) + 1][k]] ? dp[a][k] : dp[b -

(1 << k) + 1][k];

}

}st;

inline void Init()

{

memset(head, -1, sizeof head);

memset(sz, 0, sizeof sz);

pos = 0; cnt = 0; ans = 0;

for (int i = 1; i <= n; ++i) pre[i] = i;

}

inline void addedge(int u, int v)

{

edge[++pos] = Edge(v, head[u]); head[u] = pos;

}

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

Page 168: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

inline void DFS(int u)

{

F[++cnt] = u;

rmq[cnt] = deep[u];

P[u] = cnt;

for (int it = head[u]; ~it; it = edge[it].nx)

{

int v = edge[it].to;

if (v == fa[u]) continue;

fa[v] = u; deep[v] = deep[u] + 1;

DFS(v);

F[++cnt] = u;

rmq[cnt] = deep[u];

}

}

inline void init_lca(int root, int node_num)

{

fa[root] = 0; deep[0] = 0;  

DFS(root);

st.init(2 * node_num - 1);

}

inline int query_lca(int u, int v)

{

return F[st.query(P[u], P[v])];

}

inline int find(int x)

{

if (pre[x] != x)

pre[x] = find(pre[x]);

return pre[x];

}

inline void join(int x, int y)

{

x = find(x);

if (deep[fa[x]] <= deep[y] || fa[x] == 0) return;

ans ^= sz[fa[x]] ^ (sz[fa[x]] - 1);  

--sz[fa[x]];

pre[x] = fa[x];

join(fa[x], y);

}

inline void Run()

{

while (scanf("%d%d%d%d%d%d", &n, &m, &a, &b, &x, &y) != EOF)

{

Init();

for (int i = 1, u, v; i < n; ++i)

{

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

Page 169: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

 

可持久化并查集

scanf("%d%d", &u, &v); ++u, ++v; ++sz[u], ++sz[v];

addedge(u, v); addedge(v, u);

}

init_lca(1, n);

for (int i = 1; i <= n; ++i) ans ^= sz[i];  

for (int i = 1; i <= m; ++i)

{

int nx = (a * x + b * y + ans) % n;

int ny = (b * x + a * y + ans) % n;

x = nx, y = ny;  

join(x + 1, query_lca(x + 1, y + 1));

}

printf("%d %d\n", x, y);

}

}

int main()

{

#ifdef LOCAL

freopen("Test.in", "r", stdin);

#endif

Run();

return 0;

}

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

//可持久化并查集//非递归版

#include <bits/stdc++.h>

using namespace std;

#define N 20010

#define M N * 50

int n, q;

int T[N], L[M], R[M], C[M], tot;

inline int build(int l, int r)

{

int root = tot++;

if (l < r)

{

int mid = (l + r) >> 1;

L[root] = build(l, mid);

R[root] = build(mid + 1, r);

}

else

C[root] = l;

return root;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

Page 170: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

}

inline int update(int root, int pos, int val)

{

int newroot = tot++, tmp = newroot;

int l = 1, r = n;

while (l < r)

{

int mid = (l + r) >> 1;

if (pos <= mid)

{

L[newroot] = tot++, R[newroot] = R[root];

newroot = L[newroot], root = L[root];

r = mid;

}

else

{

L[newroot] = L[root], R[newroot] = tot++;

newroot = R[newroot], root = R[root];

l = mid + 1;

}

C[newroot] = val;

}

return tmp;

}

inline int query(int root, int pos)

{

int l = 1, r = n;

while (l < r)

{

int mid = (l + r) >> 1;

if (pos <= mid)

{

root = L[root];

r = mid;

}

else

{

root = R[root];

l = mid + 1;

}

}

return C[root];

}

inline int find(int &root, int x)

{

int tmp = query(root, x);

if (tmp == x) return x;

else

{

int ret = find(root, tmp);

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

Page 171: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

root = update(root, x, ret);  

return ret;

}

}

inline void Run()

{

while (scanf("%d%d", &n, &q) != EOF)

{

tot = 0; T[0] = build(1, n);

int op, a, b, k;

for (int i = 1; i <= q; ++i)

{

scanf("%d", &op);

if (op == 1)

{

scanf("%d%d", &a, &b);

int fa = find(T[i - 1], a); int fb = find(T[i - 1], b);

if (fa != fb) T[i] = update(T[i - 1], fa, fb);

else T[i] = T[i - 1];

}

else if (op == 2)

{

scanf("%d", &k);

T[i] = T[k];

}

else

{

scanf("%d%d", &a, &b);

int fa = find(T[i - 1], a), fb = find(T[i - 1], b);

puts(fa == fb ? "1" : "0");

T[i] = T[i - 1];

}

}

}

}

int main()

{

#ifdef LOCAL

freopen("Test.in", "r", stdin);

#endif

Run();

return 0;

}

//递归版

#include<iostream>

#include<cstdlib>

#include<cmath>

#include<cstring>

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

Page 172: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

#include<cstdio>

#include<algorithm>

#define F(i,j,n) for(int i=j;i<=n;i++)

#define D(i,j,n) for(int i=j;i>=n;i--)

#define ll long long

#define maxn 20005

#define maxm 3000000

using namespace std;

int n,m,p,x,y,cnt;

int rt[maxn],v[maxm],ls[maxm],rs[maxm];

inline int read()

{

   int x=0,f=1;char ch=getchar();

   while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}

   while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}

   return x*f;

}

void build(int &k,int l,int r)

{

   k=++cnt;

   if (l==r){v[k]=l;return;}

   int mid=(l+r)>>1;

   build(ls[k],l,mid);build(rs[k],mid+1,r);

}

int query(int k,int l,int r,int pos)

{

   if (l==r) return v[k];

   int mid=(l+r)>>1;

   if (pos<=mid) return query(ls[k],l,mid,pos);

   else return query(rs[k],mid+1,r,pos);

}

void insert(int x,int &y,int l,int r,int pos,int val)

{

   y=++cnt;

   if (l==r){v[y]=val;return;}

   int mid=(l+r)>>1;

   ls[y]=ls[x];rs[y]=rs[x];

   if (pos<=mid) insert(ls[x],ls[y],l,mid,pos,val);

   else insert(rs[x],rs[y],mid+1,r,pos,val);

}

int find(int &root,int x)

{

   int tmp=query(root,1,n,x);

   if (tmp==x) return x;

   else

  {

       int ret=find(root,tmp);

       insert(root,root,1,n,x,ret);

       return ret;

  }

}

int main()

{

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

Page 173: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

Trie树

   n=read();m=read();

   build(rt[0],1,n);

   F(i,1,m)

  {

       p=read();

       if (p==1)

      {

           int x=read(),y=read(),fx=find(rt[i-1],x),fy=find(rt[i-1],y);

           if (fx==fy) rt[i]=rt[i-1];

           else insert(rt[i-1],rt[i],1,n,fx,fy);

      }

       else if (p==2)

      {

           int x=read();

           rt[i]=rt[x];

      }

       else

      {

           int x=read(),y=read(),fx=find(rt[i-1],x),fy=find(rt[i-1],y);

           if (fx==fy) puts("1");

           else puts("0");

           rt[i]=rt[i-1];

      }

  }

   return 0;

}

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

//k叉

/*

* INIT: init();

* 注: tree[i][tk]>0时表示单词存在, 当然也可赋予它更多含义;

*/

const int tk = 26, tb = 'a';    // tk叉; 起始字母为tb;

const int N = 1010;             // N: 最大结点个数int top, tree[N][tk + 1];

void init()

{

   top = 1;

   memset(tree[0], 0, sizeof(tree[0]));

   return ;

}

int sear(char *s)               // 失败返回0

{

   for (int rt = 0; rt == tree[rt][*s - tb];)

  {

       if (*(++s) == 0)

      {

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

Page 174: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

           return tree[rt][tk];

      }

  }

   return 0;

}

void insert(char *s, int rank = 1)

{

   int rt, nxt;

   for (rt = 0; *s; rt = nxt, ++s)

  {

       nxt = tree[rt][*s - tb];

       if (0 == nxt)

      {

           tree[rt][*s - tb] = nxt = top;

           memset(tree[top], 0, sizeof(tree[top]));

           top++;

      }

  }

   tree[rt][tk] = rank;    // 1表示存在0表示不存在,也可以赋予其其他含义}

void delt(char *s)          // 只做标记, 假定s一定存在{

   int rt = 0;

   for (; *s; ++s)

  {

       rt = tree[rt][*s - tb];

  }

   tree[rt][tk] = 0;

   return ;

}

int prefix(char *s)         // 最长前缀{

   int rt = 0, lv;

   for (lv = 0; *s; ++s, ++lv)

  {

       rt = tree[rt][*s - tb];

       if (rt == 0)

      {

           break;

      }

  }

   return lv;

}

//左儿子右兄弟

/*

* 左孩子右兄弟 * INIT: init();

*/

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

Page 175: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

const int N = 1010;

int top;

struct trie

{

   char c;

   int l, r, rk;

} tree[N];

void init()

{

   top = 1;

   memset(tree, 0, sizeof(tree[0]));

}

int sear(char *s)   // 失败返回0

{

   int rt;

   for (rt = 0; *s; ++s)

  {

       for (rt = tree[rt].l; rt; rt = tree[rt].r)

      {

           if (tree[rt].c == *s)

          {

               break;

          }

      }

       if (rt == 0)

      {

           return 0;

      }

  }

   return tree[rt].rk;

}

void insert(char *s, int rk = 1)    // rk: 权或者标记{

   int i, rt;

   for (rt = 0; *s; ++s, rt = i)

  {

       for (i = tree[rt].l; i; i = tree[i].r)

      {

           if (tree[i].c == *s)

          {

               break;

          }

      }

       if (i == 0)

      {

           tree[top].r = tree[rt].l;

           tree[top].l = 0;

           tree[top].c = *s;

           tree[top].rk = 0;

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

Page 176: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

           tree[rt].l = top;

           i = top++;

      }

  }

   tree[rt].rk = rk;

   return ;

}

void delt(char *s)  // 假定s已经存在,只做标记{

   int rt;

   for (rt = 0; *s; ++s)

  {

       for (rt = tree[rt].l; rt; rt = tree[rt].r)

      {

           if (tree[rt].c == *s)

          {

               break;

          }

      }

       tree[rt].rk = 0;

  }

   return ;

}

int profix(char *s) // 最长前缀{

   int rt = 0, lv;

   for (lv = 0; *s; ++s, ++lv)

  {

       for (rt = tree[rt].l; rt; rt = tree[rt].r)

      {

           if (tree[rt].c == *s)

          {

               break;

          }

      }

       if (rt == 0)

      {

           break;

      }

  }

   return lv;

}

//可持久化Trie树#include <bits/stdc++.h>

using namespace std;

#define N 100010

#define ll long long

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

Page 177: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

struct Edge

{

int to, nx;

inline Edge() {}

inline Edge(int to, int nx) : to(to), nx(nx) {}

}edge[N << 1];

int head[N], tot, pos, cnt;

int fa[N], son[N], ord[N], ford[N];

int root[N];

struct node

{

int son[2], Count;

inline node()

{

memset(son, 0, sizeof son);

Count = 0;

}

}tree[N * 64];

inline void Init()

{

memset(head, -1, sizeof head);

pos = 0; tot = 0, cnt = 0;

tree[0] = node();

}

inline void addedge(int u, int v)

{

edge[++tot] = Edge(v, head[u]); head[u] = tot;

}

int n, q;

ll w[N];

inline void DFS(int u)

{

ord[u] = ++pos;

ford[pos] = u;

for (int it = head[u]; ~it; it = edge[it].nx)

{

int v = edge[it].to;

if (v == fa[u]) continue;

DFS(v);

}

son[u] = pos;

}

inline void Insert(ll x, int id)

{

bitset <32> b; b = x;

root[id] = ++cnt;

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

Page 178: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

tree[cnt] = tree[root[id - 1]];

int poss = cnt;

for (int i = 31; i >= 0; --i)

{

int index = b[i];

tree[++cnt] = tree[tree[poss].son[index]];

tree[cnt].Count++;

tree[poss].son[index] = cnt;

poss = cnt;

}

}

inline ll Query(ll x, int l, int r)

{

bitset <32> b; b = x;

ll ans = 0;

l = root[l], r = root[r];

for (int i = 31; i >= 0; --i)

{

int index = b[i] ^ 1;

bool flag = true;

if (tree[tree[r].son[index]].Count - tree[tree[l].son[index]].Count <= 0)

{

index ^= 1;

flag = false;

}

if (flag) ans += (1 << i);  

r = tree[r].son[index]; l = tree[l].son[index];

}

return ans;

}

int main()

{

while (scanf("%d%d", &n, &q) != EOF)

{

Init();

for (int i = 1; i <= n; ++i) scanf("%lld", w + i);

for (int i = 1, u; i < n; ++i)

{

scanf("%d", &u);

fa[i + 1] = u;

addedge(u, i + 1);

}

DFS(1);

for (int i = 1; i <= n; ++i)

{

Insert(w[ford[i]], i);

}

while(q--)

{

int u; ll x;

scanf("%d%lld",&u,&x);

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

Page 179: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

二分查找

int l = ord[u] - 1, r = son[u];

printf("%lld\n",Query(x, l, r));

}

}

return 0;

}

289

290

291

292

293

294

//查找v

/*

* 在[l, h)范围内查找值v,返回下标 * 假设a数组已经按从小到大排序 * 失败返回-1

*/

int bs(int a[], int l, int h, int v)

{

   int m;

   while (l < h)

  {

       m = (l + h) >> 1;

       if (a[m] == v)

      {

           return m;

      }

       if (a[m] < v)

      {

           l = m + 1;

      }

       else

      {

           h = m;

      }

  }

   return -1;

}

//查找大于等于v的第一个值

/*

* 传入参数必须在a[l]与a[h]之间 * 假设a数组已经按从小到大排序 * 返回值l总是合理的 */

int bs(int a[], int l, int h, int v)

{

   int m;

   while (l < h)

  {

       m = (l + h) >> 1;

       if (a[m] < v)

      {

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

Page 180: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

           l = m + 1;

      }

       else

      {

           h = m;

      }

  }

   return l;

}

//查找小于等于v的最后一个值

/*

* 在下标[l, r]范围内查找,返回下标 * 假设a数组已经按从小到大排序 * 失败返回-1

*/

int bs(int a[], int l, int r, int v)

{

   int m;

   while (l < r)

  {

       m = (l + r + 1) >> 1;

       if (a[m] > v)

      {

           r = m - 1;

      }

       else

      {

           l = m;

      }

  }

   if (a[l] > v)

  {

       return -1;

  }

   return l;

}

//二分套二分

/*

* 二分套二分 * 数组A同数组B组合乘积,二分查找第K大 */

typedef long long ll;

const int MAXN = 5e4 + 10;

ll N, K;

ll A[MAXN];

ll B[MAXN];

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

Page 181: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

// 查找小于x的元素个数ll check(ll x)

{

   ll j = N, ans = 0;

   for (int i = 1; i <= N; i++)

  {

       for (; j > 0;)

      {

           if (A[i] * B[j] > x)

          {

               j--;

          }

           else

          {

               break;

          }

      }

       ans += j;

  }

   return ans;

}

int main(int argc, const char * argv[])

{

   cin >> N >> K;

   for (int i = 1; i <= N; i++)

  {

       scanf("%lld %lld", A + i, B + i);

  }

   sort(A + 1, A + N + 1);

   sort(B + 1, B + N + 1);

   ll ans = 0;

   ll key = N * N - K + 1;

   ll low = A[1] * B[1];   // 初始最小值    ll high = A[N] * B[N];  // 初始最大值

   while (high - low > 1)

  {

       ll mid = (low + high) >> 1;

       if (check(mid) >= key)

      {

           ans = mid;

           high = mid;

      }

       else

      {

           low = mid;

      }

  }

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

Page 182: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

树状数组

   cout << ans << '\n';

   return 0;

}

151

152

153

// 一维 单点更新,区间查询

ll a[maxn];

void add(int x, ll val)

{

for (int i = x; i < maxn; i += lowbit(i))

a[i] += val;

}

ll sum(int x)

{

ll ans = 0;

for (int i = x; i > 0; i -= lowbit(i))

ans += a[i];

return ans;

}

/*

一维 区间修改,单点查询 思想是 差分 a[] 保存的是前缀和 那么修改的话只需要 修改区间的头部和尾部

*/

ll a[maxn]

ll sum(int x) // 查询的是单点的值  

{

ll ans = 0;

for (int i = x; i > 0; i -= lowbit(i))

ans ++ a[i];

return ans;

}

void add(int x, ll val)

{

for (int i = x; i < maxn; i += lowbit(i))

a[i] += val;

}

void update(int l, int r)  // 区间更新

{

add(l, val);

add(r + 1, -val);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

Page 183: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

/*

二维 单点更新 区间查询*/

int a[maxn][maxn];

void add(int x, int y, int val)

{

for (int i = x; i <= n; i += lowbit(i))

for (int j = y; j <= n; j += lowbit(j))

a[i][j] += val;

}

int sum(int x, int y)

{

int ans = 0;

for (int i = x; i > 0; i -= lowbit(i))

for (int j = y; j > 0; j -= lowbit(j))

ans += a[i][j];

return ans;

}

int Query(int x1, int y1, int x2, int y2)

{

int ans = 0;

ans += sum(x2, y2);

ans -= sum(x2, y1 - 1);

ans -= sum(x1 - 1, y2);

ans += sum(x1 - 1, y1 - 1);

return ans;

}

void Solve()

{

int op;

while (op = read(), op != 3)

{

if (op == 1)  // add operator

{

int x = read() + 1, y = read() + 1, v = read();

add(x, y, v);

}

else // query operator

{

int x1 = read() + 1, y1 = read() + 1, x2 = read() + 1, y2 = read() +

1;

write(Query(x1, y1, x2, y2)), p10;

}

}

return;

}

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

Page 184: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

/*

三维 区间修改 单点查询

*/

int x[2], y[2], z[2];

int a[maxn][maxn][maxn];

void add(int x, int y, int z, int val)

{

for (int i = x; i < maxn; i += lowbit(i))

for (int j = y; j < maxn; j += lowbit(j))

for (int k = z; k < maxn; k += lowbit(k))

a[i][j][k] += val;

}

int Query()

{

int ans = 0;

for (int i = x[0]; i > 0; i -= lowbit(i))

for (int j = y[0]; j > 0; j -= lowbit(j))

for (int k = z[0]; k > 0; k -= lowbit(k))

ans += a[i][j][k];

return (ans & 1);

}

void update()

{

add(x[0], y[0], z[0], n);

add(x[1] + 1, y[0], z[0], -n); add(x[0], y[1] + 1, z[0], -n); add(x[0], y[0],

z[1] + 1, -n);

add(x[0], y[1] + 1, z[1] + 1, n); add(x[1] + 1, y[0], z[1] + 1, n); add(x[1] +

1, y[1] + 1, z[0], n);

add(x[1] + 1, y[1] +1, z[1] + 1, -n);  

}

//区间查询最值  

int n, m;

int arr[maxn];

int h[maxn];

inline void update(int x)

{

for (int i = x; i <= n; i += lowbit(i))

{

h[i] = arr[i];

int li = lowbit(i);

for (int j = 1; j < li; j <<= 1)

h[i] = max(h[i], h[i - j]);  

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

Page 185: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

滚动数组

}

}

inline int query(int l, int r)

{

int ans = 0;

for (int i = r; i >= l;)

{

ans = max(arr[i], ans);

for (i--; i - lowbit(i) >= l; i -= lowbit(i))

ans = max(h[i], ans);

}

return ans;

}

inline void Solve()

{

char op; int a, b;

F(i, 1, n) update(i);

F(i, 1, m)

{

__read(op); __read(a), __read(b);

if (op == 'Q')

write(query(a, b)), p10;

else

{

arr[a] = b;

update(a);

}

}

}

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

//一维

int main()

{

   int i;

   long long d[80];

   d[0] = 1;

   d[1] = 1;

   for(i = 2; i < 80; i++)

  {

       d[i] = d[i - 1] + d[i - 2];

  }

   printf("%lld\n",d[79]);

   return 0;

}

//上面这个循环d[i]只依赖于前两个数据d[i - 1]和d[i - 2]; 为了节约空间用滚动数组的做法。

int main()

{

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

Page 186: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

   int i;

   long long d[3];

   d[0] = 1;

   d[1] = 1;

   for(i = 2; i < 80; i++)

  {

       d[i % 3] = d[(i - 1) % 3] + d[(i - 2) % 3];

  }

   printf("%lld\n", d[79%3]);

   return 0;

}

//上面的取余运算,我们成功地只保留了需要的最后3个解,数组好象在“滚动”一样,所以叫滚动数组(对于二维也可以用)。所以,很明显,滚动数组可以通过取余(%)来实现的,但是这里存在一个通病,那就是时间换内存一定会牺牲时间。因此,滚动数组一般用在时间比较充裕,而内存不够的情况下。

//二维

//对于二维数组,我们可以这样子改造:

int i, j, d[100][100];

for(i = 1; i < 100; i++)

   for(j = 0; j < 100; j++)

       d[i][j] = d[i - 1][j] + d[i][j - 1];

//上面的d[i][j]只依赖于d[i - 1][j], d[i][j - 1];

//运用滚动数组

int i, j, d[2][100];

for(i = 1; i < 100; i++)

   for(j = 0; j < 100; j++)

       d[i % 2][j] = d[(i - 1) % 2][j] + d[i % 2][j - 1];

//附录

//附上另外一种滚动数组的写法(其实和取余一个路子)://斐波那契数列……

int Fib[3];

int fib(int n)

{

   Fib[1] = 0;

   Fib[2] = 1;

   for(int i = 2; i <= n; ++i)

  {

       Fib[0] = Fib[1];

       Fib[1] = Fib[2];

       Fib[2] = Fib[0] + Fib[1];

  }

   return Fib[2];

}

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

Page 187: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

堆栈

int main()

{

   int ncase, n, ans;

   scanf("%d", &ncase);

   while(ncase--)

  {

       scanf("%d", &n);

       ans = fib(n);

       printf("%d\n", ans);

  }

   return 0;

}

71

72

73

74

75

76

77

78

79

80

81

82

const int MAXSIZE = 10000;

int a[MAXSIZE], heapsize;

inline void swap(int i, int j)

{

   int temp = a[i];

   a[i] = a[j];

   a[j] = temp;

   return ;

}

inline int Parent(int i)

{

   return i >> 1;

}

inline int Left(int i)

{

   return 1 << i;

}

inline int Right(int i)

{

   return (1 << i) + 1;    // 保持堆的性质}

void MaxHeapify(int i)

{

   int l = Left(i), r = Right(i), largest;

   if (l <= heapsize && a[l] > a[i])

  {

       largest = l;

  }

   else

  {

       largest = i;

  }

   if (r <= heapsize && a[r] > a[largest])

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

Page 188: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

 

块状链表

  {

       largest = r;

  }

   if (largest != i)

  {

       swap(i, largest);

       MaxHeapify(largest);

  }

   return ;

}

void BuildMaxHeap(int *arr, int n)

{

   heapsize = n;

   for (int i = heapsize / 2; i > 0; --i)

  {

       MaxHeapify(i);

  }

   return ;

}

void HeapSort(int *arr, int n)

{

   BuildMaxHeap(arr, n);

   for (int i = n; i > 1; --i)

  {

       swap(1, i);

       heapsize--;

       MaxHeapify(1);

  }

   return ;

}

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

#include <cstdio>

#include <cstring>

#include <algorithm>

using namespace std;

#define N 4010

struct node

{

   int size;

   char data[N];

   inline node() // Count from ONE

  {

       size = 0;

       memset(data, 0, sizeof data);

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

Page 189: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

  }

   inline void push_back(char ch)

  {

       size++;

       data[size] = ch;

  }

   inline void Insert(int pos, char ch)

  {

       for (int i = size + 1; i > pos; i--)

           data[i] = data[i - 1];

       size++;

       data[pos] = ch;

  }

   inline char Get(int pos)

  {

       return data[pos];

  }

}point[N];

#define M 1000010

char s[M];

int sum[N], cnt;

int tot;

inline void maintain()

{

   sum[0] = 0; tot = 0;

   for (int i = 1; i <= cnt; i++)

       sum[i] = sum[i - 1] + point[i].size;

   tot = sum[cnt];

}

inline void Init()

{

   cnt = 0;

   for (int i = 0; s[i]; i++)

  {

       if (i % 1000 == 0) cnt++, point[cnt] = node();

       point[cnt].push_back(s[i]);

  }

   maintain();

}

inline void Insert(int pos, char ch)

{

   int p = lower_bound(sum + 1, sum + 1 + cnt, pos) - sum;

   pos -= sum[p - 1];

   point[p].Insert(pos, ch);

   maintain();

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

Page 190: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

主席树求第k大多维护sum

}

inline char Get(int pos)

{

   int p = lower_bound(sum + 1, sum + 1 + cnt, pos) - sum;

   pos -= sum[p - 1];

   return point[p].Get(pos);    

}

int n;

int main()

{

   while (scanf("%s", s) != EOF)

  {

       Init();

       scanf("%d", &n);

       char op, ch; int p;

       while (n--)

      {

           scanf(" %c", &op);

           if (op == 'I')

          {

               scanf(" %c%d", &ch, &p);

               if (p <= tot)

                   Insert(p, ch);

               else

              {

                   point[cnt].push_back(ch);

                   maintain();

              }

          }

           else

          {

               scanf("%d", &p);

               printf("%c\n", Get(p));

          }

      }

  }

}

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

// 主席树 求区间第k大 多维护了一个数字 sum[] 求出第k大的同时 顺便求出第k大左边的数的和 以及右边的和

int n, q, m, tt, kase = 1;

int T[maxn], lson[Maxn], rson[Maxn], c[Maxn], tot;

ll sum[Maxn], pre_sum[maxn], a[maxn], tmp[maxn], leftsum, rightsum, midnum, ans;  

inline void Init()

{

tot = 0; CLR(sum, 0); CLR(c, 0);

}

1

2

3

4

5

6

7

8

9

Page 191: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

inline int build(int l, int r)

{

int root = tot++;

if (l != r)

{

int mid = (l + r) >> 1;

lson[root] = build(l, mid);

rson[root] = build(mid + 1, r);

}

return root;

}

inline int update(int root, int pos, ll val)

{

int newroot = tot++; int tmp = newroot;

c[newroot] = c[root] + 1;

sum[newroot] = sum[root] + val;  

int l = 1, r = m;

while (l < r)

{

int mid = (l + r) >> 1;

if (pos <= mid)

{

lson[newroot] = tot++; rson[newroot] = rson[root];

newroot = lson[newroot]; root = lson[root];

r = mid;

}

else

{

rson[newroot] = tot++; lson[newroot] = lson[root];

newroot = rson[newroot]; root = rson[root];

l = mid + 1;

}

c[newroot] = c[root] + 1;  

sum[newroot] = sum[root] + val;   // 多维护的一个数组

}

return tmp;

}

inline int query(int leftroot, int rightroot, int k)

{

int l = 1, r = m;

while (l < r)

{

int mid = (l + r) >> 1;

if (c[lson[leftroot]] - c[lson[rightroot]] >= k)  

{

r = mid;

leftroot = lson[leftroot];

rightroot = lson[rightroot];

}

else

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

Page 192: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

LCA倍增维护距离

{

l = mid + 1;

k -= c[lson[leftroot]] - c[lson[rightroot]];

leftsum += sum[lson[leftroot]] - sum[lson[rightroot]];

leftroot = rson[leftroot];

rightroot = rson[rightroot];  

}

}

leftsum += k * tmp[l]; // 因为是权值线段树,要考虑重复的怎么处理

return l;  

}

inline void Init_hash()

{

F(i, 1, n) tmp[i] = a[i];

sort(tmp + 1, tmp + 1 + n);

m = unique(tmp + 1, tmp + 1 + n) - tmp - 1;

}

inline int Hash(ll x)

{

return lower_bound(tmp + 1, tmp + 1 + m, x) - tmp;

}

inline bool Input()

{

if (tt-- == 0) return false;

scanf("%d", &n); Init(); pre_sum[0] = 0;

F(i, 1, n) scanf("%d", a + i), pre_sum[i] = pre_sum[i - 1] + a[i];

return true;

}

inline void Solve()

{

printf("Case #%d:\n", kase++);

Init_hash(); T[n + 1] = build(1, m);  

FF(i, n, 1) T[i] = update(T[i + 1], Hash(a[i]), a[i]);

scanf("%d", &q); int l, r, k;

while (q--)

{

scanf("%d%d", &l, &r); l++, r++;

k = (r - l + 2) >> 1;

leftsum = 0;

midnum = tmp[query(T[l], T[r + 1], k)];

rightsum = pre_sum[r] - pre_sum[l - 1] - leftsum;

ans = midnum * k - leftsum + rightsum - (r - l + 1 - k) * midnum;

output(ans);

}

p10;

}

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

Page 193: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

// LCA 倍增维护距离

#include <bits/stdc++.h>

using namespace std;

#define N 100010

#define DEG 25

#define INF 0x3f3f3f3f

struct Edge

{

int to, nx, w;

inline Edge() {}

inline Edge(int to, int nx, int w) : to(to), nx(nx), w(w) {}

}edge[N << 1];

int t, n, m, q;

int fa[N][DEG], dis[N][DEG];

int deg[N];

int head[N], pos;    

inline void Init()

{

memset(head, -1, sizeof head); pos = 0;  

}

inline void addedge(int u, int v, int w)

{

edge[++pos] = Edge(v, head[u], w); head[u] = pos;

edge[++pos] = Edge(u, head[v], w); head[v] = pos;  

}

inline void BFS()

{

queue <int> q; deg[1] = 0; fa[1][0] = 1; dis[1][0] = 0; q.emplace(1);

while (!q.empty())  

{

int u = q.front(); q.pop();  

for (int i = 1; i < DEG; ++i)  

{

dis[u][i] = dis[u][i - 1] + dis[fa[u][i - 1]][i - 1];  

fa[u][i] = fa[fa[u][i - 1]][i - 1];

}

for (int it = head[u]; ~it; it = edge[it].nx)

{

int v = edge[it].to, w = edge[it].w;

if (v == fa[u][0]) continue;

deg[v] = deg[u] + 1;  

fa[v][0] = u; dis[v][0] = w;  

q.emplace(v);  

}

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

Page 194: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

inline int query(int u, int v)

{

if (u == v) return 0;

if (deg[u] > deg[v]) swap(u, v);

int res = 0, hu = deg[u], hv = deg[v], tu = u, tv = v;

for (int det = hv - hu, i = 0; det; det >>= 1, ++i)

{

if (det & 1)

{

res += dis[tv][i];    

tv = fa[tv][i];  

}

}

if (tu == tv) return res;    

for (int i = DEG - 1; i >= 0; --i)

{

if (fa[tu][i] == fa[tv][i]) continue;

res += dis[tu][i] + dis[tv][i];  

tu = fa[tu][i]; tv = fa[tv][i];  

}

return res + dis[tu][0] + dis[tv][0];  

}

struct node

{

vector <int> v; int len;  

inline void scan()

{

scanf("%d", &len); v.clear();  

for (int i = 1, u; i <= len; ++i)

{

scanf("%d", &u);  

v.emplace_back(u);  

}

}

}arr[N];

inline void Run()

{

scanf("%d", &t);

while (t--)

{

scanf("%d%d", &n, &m); Init();

for (int i = 1, u, v, w; i < n; ++i)

{

scanf("%d%d%d", &u, &v, &w);

addedge(u, v, w);  

} BFS();

for (int i = 1; i <= m; ++i) arr[i].scan();

scanf("%d", &q);    

for (int i = 1, u, v; i <= q; ++i)

{

scanf("%d%d", &u, &v);

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

Page 195: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

计算几何 Andrew求凸包

int ans = INF;

for (auto it : arr[u].v) for (auto it2 : arr[v].v) ans = min(ans,

query(it, it2));

printf("%d\n", ans);  

}

}

}

int main()

{

#ifdef LOCAL

freopen("Test.in", "r", stdin);

#endif

Run();

return 0;

}

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <algorithm>

#include <cmath>

using namespace std;

const double eps = 1e-8,Pi=3.14159265;

int n;

inline int dcmp(double x)//三态函数{

if(fabs(x) < eps) return 0;

else return x>0 ? 1 : -1;

}

#define Vector Point

struct Point

{

double x,y;

inline Point(double x=0,double y=0):x(x),y(y) {}

}p[10000+5],ch[10000+5];

bool myCmp(Point A, Point B)

{

if(A.x != B.x) return A.x < B.x;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

Page 196: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

else return A.y < B.y;

}

Vector operator + (Vector A, Vector B) {return Vector(A.x + B.x, A.y + B.y);}

Vector operator - (Vector A, Vector B) {return Vector(A.x - B.x, A.y - B.y);}

bool operator == (const Vector& A, const Vector& B) {return dcmp(A.x-B.x)==0 &&

dcmp(A.y-B.y)==0;}

inline double Cross(Vector A, Vector B)//叉积{

return A.x * B.y - A.y * B.x;

}

int ConvexHull()

{

sort(p,p+n,myCmp);

int m = 0;

for(int i = 0; i <n; i++)

{

while(m > 1 && dcmp(Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2])) <= 0) m--;

ch[m++] = p[i];

}

int k = m;

for(int i = n-2; i >= 0; i--)

{

while(m > k && dcmp(Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2])) <= 0) m--;

ch[m++] = p[i];

}

if(n > 1) m--;

return m;

}

double Dis(Point A, Point B)

{

return sqrt((A.x - B.x)*(A.x - B.x) + (A.y - B.y)*(A.y - B.y));

}

int main()

{

int m;

cin>>n;

for(int i = 0; i < n; i++)

{

int a,b;

cin>>a>>b;

p[i] = Point(a,b);

}

m = ConvexHull();

//计算凸包周长

double ans=0.0;

for(int i = 0; i < m-1; i++)

ans += Dis(ch[i],ch[i+1]);

ans += Dis(ch[m-1],ch[0]);

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

Page 197: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

判断四点共面

求多边形重心

printf("%.1f",ans);

}

82

83

84

struct  point

{

   double x, y, z;

   point  operator - (point &o)

  {

       point  ans;

       ans.x = this->x - o.x;

       ans.y = this->y - o.y;

       ans.z = this->z - o.z;

       return ans;

  }

};

double  dot_product(const point &a, const point &b)

{

   return a.x * b.x + a.y * b.y + a.z * b.z;

}

point cross_product(const point &a, const point &b)

{

   point  ans;

   ans.x = a.y * b.z - a.z * b.y;

   ans.y = a.z * b.x - a.x * b.z;

   ans.z = a.x * b.y - a.y * b.x;

   return ans;

}

int main()

{

   point p[4];

   int T;

   for (scanf("%d", &T); T--;)

  {

       for (int i = 0; i < 4; ++i)

      {

           scanf("%lf%lf%lf", &p[i].x, &p[i].y, &p[i].z);

      }

       puts(dot_product(p[3] - p[0], cross_product(p[2] - p[0], p[1] - p[0])) ==

0.0 ? "Yes\n" : "No\n");

  }

   return 0;

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

/*1

Page 198: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

三角形相关重点

* 求多边形重心 * INIT: pnt[]已按顺时针(或逆时针)排好序; | CALL: res = bcenter(pnt, n);

*/

struct point

{

   double x, y;

};

point bcenter(point pnt[], int n)

{

   point p, s;

   double tp, area = 0, tpx = 0, tpy = 0;

   p.x = pnt[0].x;

   p.y = pnt[0].y;

   for (int i = 1; i <= n; ++i)

  {   // point:0 ~ n - 1

       s.x = pnt[(i == n) ? 0 : i].x;

       s.y = pnt[(i == n) ? 0 : i].y;

       tp = (p.x * s.y - s.x * p.y);

       area += tp / 2;

       tpx += (p.x + s.x) * tp;

       tpy += (p.y + s.y) * tp;

       p.x = s.x;

       p.y = s.y;

  }

   s.x = tpx / (6 * area);

   s.y = tpy / (6 * area);

   return s;

}

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

//三角形重点

//设三角形的三条边为a, b, c, 且不妨假设a <= b <= c.

//面积

//三角形面积可以根据海伦公式求得:

   s = sqrt(p * (p - a) * (p - b) * (p - c));

   p = (a + b + c) / 2;

//关键点与A, B, C三顶点距离之和/*

费马点

该点到三角形三个顶点的距离之和最小。有个有趣的结论:

若三角形的三个内角均小于120度,那么该点连接三个顶点形成的三个角均为120度;若三角形存在一个内角大于120度,则该顶点就是费马点。计算公式如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

Page 199: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

旋转卡壳

若有一个内角大于120度(这里假设为角C),则距离为a + b;若三个内角均小于120度,则距离为sqrt((a * a +

b * b + c * c + 4 * sqrt(3.0) * s) / 2)。内心

角平分线的交点。令x = (a + b - c) / 2, y = (a - b + c) / 2, z = (-a + b + c) / 2, h = s / p.

计算公式为sqrt(x * x + h * h) + sqrt(y * y + h * h) + sqrt(z * z + h * h)。重心

中线的交点。计算公式如下:

2.0 / 3 * (sqrt((2 * (a * a + b * b) - c * c) / 4)

+ sqrt((2 * (a * a + c * c) - b * b) / 4) + sqrt((2 * (b * b + c * c) - a * a) /

4))。垂心

垂线的交点。计算公式如下:

3 * (c / 2 / sqrt(1 - cosC * cosC))。外心

三点求圆心坐标。*/

Point waixin(Point a, Point b, Point c)

{

   double a1 = b.x - a.x, b1 = b.y - a.y, c1 = (a1 * a1 + b1 * b1) / 2;

   double a2 = c.x - a.x, b2 = c.y - a.y, c2 = (a2 * a2 + b2 * b2) / 2;

   double d = a1 * b2 - a2 * b1;

   return Point(a.x + (c1 * b2 - c2 * b1) / d, a.y + (a1 * c2 -a2 * c1) / d);

}

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

//求解平面最远点对

struct Point

{

   int x, y;

   Point(int _x = 0, int _y = 0)

  {

       x = _x;

       y = _y;

  }

   Point operator - (const Point &b)const

  {

       return Point(x - b.x, y - b.y);

  }

   int operator ^(const Point &b)const

  {

       return x * b.y - y * b.x;

  }

   int operator *(const Point &b)const

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

Page 200: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

  {

       return x * b.x + y * b.y;

  }

   void input()

  {

       scanf("%d%d", &x, &y);

       return ;

  }

};

// 距离的平方int dist2(Point a, Point b)

{

   return (a - b) * (a - b);

}

// 二维凸包,int

const int MAXN = 50010;

Point list[MAXN];

int Stack[MAXN], top;

bool _cmp(Point p1, Point p2)

{

   int tmp = (p1 - list[0]) ^ (p2 - list[0]);

   if (tmp > 0)

  {

       return true;

  }

   else if (tmp == 0 && dist2(p1, list[0]) <= dist2(p2, list[0]))

  {

       return true;

  }

   else

  {

       return false;

  }

}

void Graham(int n)

{

   Point p0;

   int k = 0;

   p0 = list[0];

   for (int i = 1; i < n; i++)

  {

       if (p0.y > list[i].y || (p0.y == list[i].y && p0.x > list[i].x))

      {

           p0 = list[i];

           k = i;

      }

  }

   swap(list[k], list[0]);

   sort(list + 1, list + n, _cmp);

   if (n == 1)

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

Page 201: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

  {

       top = 1;

       Stack[0] = 0;

       return ;

  }

   if (n == 2)

  {

       top = 2;

       Stack[0] = 0;

       Stack[1] = 1;

       return ;

  }

   Stack[0] = 0;

   Stack[1] = 1;

   top = 2;

   for (int i = 2; i < n; i++)

  {

       while (top > 1 && ((list[Stack[top - 1]] - list[Stack[top - 2]]) ^

(list[i] - list[Stack[top - 2]])) <= 0)

      {

           top--;

      }

       Stack[top++] = i;

  }

   return ;

}

// 旋转卡壳,求两点间距离平方的最大值int rotating_calipers(Point p[],int n)

{

   int ans = 0;

   Point v;

   int cur = 1;

   for (int i = 0; i < n; i++)

  {

       v = p[i] - p[(i + 1) % n];

       while ((v ^ (p[(cur + 1) % n] - p[cur])) < 0)

      {

           cur = (cur + 1) % n;

      }

       ans = max(ans, max(dist2(p[i], p[cur]), dist2(p[(i + 1) % n], p[(cur + 1)

% n])));

  }

   return ans;

}

Point p[MAXN];

int main()

{

   int n;

   while (scanf("%d", &n) == 1)

  {

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

Page 202: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       for (int i = 0; i < n; i++)

      {

           list[i].input();

      }

       Graham(n);

       for (int i = 0; i < top; i++)

      {

           p[i] = list[Stack[i]];

      }

       printf("%d\n", rotating_calipers(p, top));

  }

   return 0;

}

//求解平面点集最大三角形

struct Point

{

   int x, y;

   Point(int _x = 0, int _y = 0)

  {

       x = _x;

       y = _y;

  }

   Point operator - (const Point &b)const

  {

       return Point(x - b.x, y - b.y);

  }

   int operator ^(const Point &b)const

  {

       return x * b.y - y * b.x;

  }

   int operator *(const Point &b)const

  {

       return x * b.x + y * b.y;

  }

   void input()

  {

       scanf("%d%d", &x, &y);

       return ;

  }

};

// 距离的平方int dist2(Point a, Point b)

{

   return (a - b) * (a - b);

}

// 二维凸包,int

const int MAXN = 50010;

Point list[MAXN];

int Stack[MAXN], top;

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

Page 203: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

bool _cmp(Point p1, Point p2)

{

   int tmp = (p1 - list[0]) ^ (p2 - list[0]);

   if (tmp > 0)

  {

       return true;

  }

   else if (tmp == 0 && dist2(p1, list[0]) <= dist2(p2, list[0]))

  {

       return true;

  }

   else

  {

       return false;

  }

}

void Graham(int n)

{

   Point p0;

   int k = 0;

   p0 = list[0];

   for (int i = 1; i < n; i++)

  {

       if (p0.y > list[i].y || (p0.y == list[i].y && p0.x > list[i].x))

      {

           p0 = list[i];

           k = i;

      }

  }

   swap(list[k], list[0]);

   sort(list + 1, list + n, _cmp);

   if (n == 1)

  {

       top = 1;

       Stack[0] = 0;

       return ;

  }

   if (n == 2)

  {

       top = 2;

       Stack[0] = 0;

       Stack[1] = 1;

       return ;

  }

   Stack[0] = 0;

   Stack[1] = 1;

   top = 2;

   for (int i = 2; i < n; i++)

  {

       while (top > 1 && ((list[Stack[top - 1]] - list[Stack[top - 2]]) ^

(list[i] - list[Stack[top - 2]])) <= 0)

      {

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

Page 204: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

           top--;

      }

       Stack[top++] = i;

  }

   return ;

}

int rotating_calipers(Point p[], int n)

{

   int ans = 0;

   Point v;

   for (int i = 0; i < n; i++)

  {

       int j = (i + 1) % n;

       int k = (j + 1) % n;

       while (j != i && k != i)

      {

           ans = max(ans, abs((p[j] - p[i]) ^ (p[k] - p[i])));

           while (((p[i] - p[j]) ^ (p[(k + 1) % n] - p[k])) < 0)

          {

               k = (k + 1) % n;

          }

           j = (j + 1) % n;

      }

  }

   return ans;

}

Point p[MAXN];

int main()

{

   int n;

   while (scanf("%d",&n) == 1)

  {

       if (n == -1)

      {

           break;

      }

       for (int i = 0; i < n; i++)

      {

           list[i].input();

      }

       Graham(n);

       for (int i = 0; i < top; i++)

      {

           p[i] = list[Stack[i]];

      }

       printf("%.2f\n", (double)rotating_calipers(p, top) / 2);

  }

   return 0;

}

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

Page 205: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

//求解两凸包最小距离

const double eps = 1e-8;

int sgn(double x)

{

   if (fabs(x) < eps)

  {

       return 0;

  }

   if (x < 0)

  {

       return -1;

  }

   else

  {

       return 1;

  }

}

struct Point

{

   double x, y;

   Point(double _x = 0, double _y = 0)

  {

       x = _x;

       y = _y;

  }

   Point operator - (const Point &b)const

  {

       return Point(x - b.x, y - b.y);

  }

   double operator ^ (const Point &b)const

  {

       return x * b.y - y * b.x;

  }

   double operator * (const Point &b)const

  {

       return x * b.x + y * b.y;

  }

   void input()

  {

       scanf("%lf%lf", &x, &y);

  }

};

struct Line

{

   Point s, e;

   Line(){}

   Line(Point _s, Point _e)

  {

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

Page 206: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       s = _s;

       e = _e;

  }

};

// 两点间距离double dist(Point a, Point b)

{

   return sqrt((a - b) * (a - b));

}

// 点到线段的距离,返回点到线段最近的点Point NearestPointToLineSeg(Point P, Line L)

{

   Point result;

   double t = ((P - L.s) * (L.e - L.s)) / ((L.e - L.s) * (L.e - L.s));

   if (t >=0 && t <= 1)

  {

       result.x = L.s.x + (L.e.x - L.s.x) * t;

       result.y = L.s.y + (L.e.y - L.s.y) * t;

  }

   else

  {

       if (dist(P,L.s) < dist(P,L.e))

      {

           result = L.s;

      }

       else

      {

           result = L.e;

      }

  }

   return result;

}

/*

* 求凸包,Graham算法 * 点的编号0~n-1

* 返回凸包结果Stack[0~top-1]为凸包的编号

*/

const int MAXN = 10010;

Point list[MAXN];

int Stack[MAXN], top;   // 相对于list[0]的极角排序bool _cmp(Point p1, Point p2)

{

   double tmp = (p1 - list[0]) ^ (p2 - list[0]);

   if (sgn(tmp) > 0)

  {

       return true;

  }

   else if (sgn(tmp) == 0 && sgn(dist(p1, list[0]) - dist(p2, list[0])) <= 0)

  {

       return true;

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

Page 207: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

  }

   else

  {

       return false;

  }

}

void Graham(int n)

{

   Point p0;

   int k = 0;

   p0 = list[0];   // 找最下边的一个点    for (int i = 1; i < n; i++)

  {

       if ((p0.y > list[i].y) || (p0.y == list[i].y && p0.x > list[i].x))

      {

           p0 = list[i];

           k = i;

      }

  }

   swap(list[k], list[0]);

   sort(list + 1, list + n, _cmp);

   if (n == 1)

  {

       top = 1;

       Stack[0] = 0;

       return ;

  }

   if (n == 2)

  {

       top = 2;

       Stack[0] = 0;

       Stack[1] = 1;

       return ;

  }

   Stack[0] = 0;

   Stack[1] = 1;

   top = 2;

   for (int i = 2; i < n; i++)

  {

       while (top > 1 && sgn((list[Stack[top - 1]] - list[Stack[top - 2]]) ^

(list[i] - list[Stack[top - 2]])) <= 0)

      {

           top--;

      }

       Stack[top++] = i;

  }

   return ;

}

// 点p0到线段p1p2的距离double pointtoseg(Point p0, Point p1, Point p2)

{

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

Page 208: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

   return dist(p0, NearestPointToLineSeg(p0, Line(p1, p2)));

}

// 平行线段p0p1和p2p3的距离double dispallseg(Point p0, Point p1, Point p2, Point p3)

{

   double ans1 = min(pointtoseg(p0, p2, p3), pointtoseg(p1, p2, p3));

   double ans2 = min(pointtoseg(p2, p0, p1), pointtoseg(p3, p0, p1));

   return min(ans1, ans2);

}

// 得到向量a1a2和b1b2的位置关系double Get_angle(Point a1, Point a2, Point b1, Point b2)

{

   return (a2 - a1) ^ (b1 - b2);

}

double rotating_calipers(Point p[], int np, Point q[], int nq)

{

   int sp = 0, sq = 0;

   for (int i = 0; i < np; i++)

  {

       if (sgn(p[i].y - p[sp].y) < 0)

      {

           sp = i;

      }

  }

   for (int i = 0; i < nq; i++)

  {

       if (sgn(q[i].y - q[sq].y) > 0)

      {

           sq = i;

      }

  }

   double tmp;

   double ans = dist(p[sp], q[sq]);

   for (int i = 0; i < np; i++)

  {

       while (sgn(tmp = Get_angle(p[sp], p[(sp + 1) % np], q[sq], q[(sq + 1) %

nq])) < 0)

      {

           sq = (sq + 1) % nq;

      }

       if (sgn(tmp) == 0)

      {

           ans = min(ans, dispallseg(p[sp], p[(sp + 1) % np], q[sq], q[(sq + 1) %

nq]));

      }

       else

      {

           ans = min(ans, pointtoseg(q[sq], p[sp], p[(sp + 1) % np]));

      }

       sp = (sp + 1) % np;

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466

467

468

469

470

471

472

473

474

475

476

477

478

479

480

481

482

483

484

485

486

487

488

489

490

Page 209: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

 

其他 c++Head

  }

   return ans;

}

double solve(Point p[], int n, Point q[], int m)

{

   return min(rotating_calipers(p, n, q, m), rotating_calipers(q, m, p, n));

}

Point p[MAXN], q[MAXN];

int main()

{

   int n, m;

   while (scanf("%d%d", &n, &m) == 2)

  {

       if (n == 0 && m == 0)

      {

           break;

      }

       for (int i = 0; i < n; i++)

      {

           list[i].input();

      }

       Graham(n);

       for (int i = 0; i < top; i++)

      {

           p[i] = list[i];

      }

       n = top;

       for (int i = 0; i < m; i++)

      {

           list[i].input();

      }

       Graham(m);

       for (int i = 0; i < top; i++)

      {

           q[i] = list[i];

      }

       m = top;

       printf("%.4f\n", solve(p, n, q, m));

  }

   return 0;

}

491

492

493

494

495

496

497

498

499

500

501

502

503

504

505

506

507

508

509

510

511

512

513

514

515

516

517

518

519

520

521

522

523

524

525

526

527

528

529

530

531

532

533

534

#pragma comment(linker, "/STACK:102400000,102400000")1

Page 210: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

#include <cstdio>

#include <cstring>

#include <cctype>

#include <cstdlib>

#include <cmath>

#include <climits>

#include <ctime>

#include <iostream>

#include <algorithm>

#include <deque>

#include <vector>

#include <queue>

#include <string>

#include <map>

#include <stack>

#include <set>

#include <list>

#include <bitset>

#include <numeric>

#include <sstream>

#include <iomanip>

#include <limits>

/**/

using namespace std;  

namespace Dup4

{

   typedef long long ll;

   typedef long double ld;

   typedef unsigned long long ull;

   typedef pair <int, int> pii;

   typedef pair <ll, ll> pll;

   typedef pair <ll, int> pli;

   typedef vector <int> vi;

   #define fi first

   #define se second

   #define pb push_back

   #define eb emplace_back

   #define gc getchar

   #define pc putchar

   #define p32 pc(' ')

   #define p10 pc('\n')

   #define lowbit(x) ((x)&(-x))

   #define mkp(a, b) make_pair(a, b)

   #define all(x) x.begin(), x.end()

   #define rall(x) x.rbegin(), x.rend()

   #define CLR(a, b) memset(a, (b), sizeof(a));

   #define random(a,b) ((a)+rand()%((b)-(a)+1))

   #define close() ios::sync_with_stdio(false); cin.tie(0);

   #define F(i, a, b) for (int i = (a); i <= (b); ++i)

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

Page 211: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

   #define FF(i, a, b) for (int i = (a); i >= (b); --i)

   inline int read()

  {

       int x = 0, f = 1; char c = gc();

       for (; !isdigit(c); c = gc()) f ^= (c == '-');

       for (; isdigit(c); c = gc()) x = x * 10 + (c - '0');

       return x * (f ? 1 : -1);

  }

   template <typename T>

   inline void read(T &x)

  {

       x = 0; int f = 1; char c = gc();

       for (; !isdigit(c); c = gc()) f ^= (c == '-');

       for (; isdigit(c); c = gc()) x = x * 10 + (c - '0');

       x *= f ? 1 : -1;

  }

   template <typename T>

   inline void out(T x)

  {

       if (!x) { pc(48); return; }

       if (x < 0) x = -x, pc('-');

       int bit[20], i, p = 0;

       for (; x; x /= 10) bit[++p] = x % 10;

       for (i = p; i; --i) pc(bit[i] + 48);

  }

   template <typename T>

   inline void output(T x) { out(x), p10; }

   template <typename T>

   inline T gcd(T a, T b)

  {

       while (b ^= a ^= b ^= a %= b);

       return a;

  }

   #ifdef LOCAL

       #define gets gets_s

       #define pause system("pause");

       #define bug puts("***bug***");

       #define debug(x) printf("#-> %d\n", x);

   #endif

   const double PI = acos(-1.0);

   const double EI = exp(1.0);

   const double eps = 1e-8;

   const int INF = 0x3f3f3f3f;

   const ll INFLL = 0x3f3f3f3f3f3f3f3fll;

}

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

Page 212: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

using namespace Dup4;

namespace FastIO

{

   // 只可读入 整数,单字符    #define BUF_SIZE 10000005

   bool IOerror = false;

   inline char NC()

  {

       static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;

       if (p1 == pend)

      {

           p1 = buf;

           pend = buf + fread(buf, 1, BUF_SIZE, stdin);

           if (pend == p1)

          {

               IOerror = true;

               return -1;

          }

      }

       return *p1++;

  }

   inline bool blank(char ch)

  {

       return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';

  }

   inline void __read(char &x)

  {

       char ch;

       while (blank(ch = NC()));

       if (IOerror)

      {

           x = -1;

           return;

      }

       x = ch;

  }

   template <typename T>

   inline void __read(T &x)

  {

       char ch;

       while (blank(ch = NC()));

       if (IOerror)

      {

           x = -1;

           return;

      }

       bool flag = false;

       if (ch == '-')

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

Page 213: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

JavaHead

      {

           flag = true;

           ch = NC();

      }

       if (!isdigit(ch)) while (!isdigit(ch = NC()));

       for (x = ch - '0'; isdigit(ch = NC()); x = x * 10 + ch - '0');

       if (flag)

           x *= -1;

  }

   #undef BUF_SIZE

}

using namespace FastIO;  

const int maxn = (int)1e6 + 10;  

const int Maxn = (int)1e4 + 10;

const int MOD = (int)1e9 + 7;

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

import java.math.*;

import java.util.*;

import java.io.*;

public class Main

{  

   InputStream in;

   PrintWriter out;

   static int maxn = (int)1e3 + 10;

   void Solve()

  {

//     返回EOF

//     try { n = nextInt(); }

//     catch (Exception ex) { return; }

//     Scanner cin = new Scanner(System.in);

       int n = nextInt();

       out.println(n);

  }

   void Run() throws Exception

  {

       in = System.in;

       out = new PrintWriter(System.out);

       Solve();

       out.flush();

  }

   public static void main(String[] args) throws Exception { new Main().Run(); }

   private byte[] inbuf = new byte[1024];

   private int lenbuf = 0, ptrbuf = 0;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

Page 214: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

   private int readByte()

  {

       if (lenbuf == -1) throw new InputMismatchException();

       if (ptrbuf >= lenbuf)

      {

           ptrbuf = 0;

           try { lenbuf = in.read(inbuf); } catch (IOException e) { throw new

InputMismatchException(); }

           if (lenbuf <= 0) return -1;

      }

       return inbuf[ptrbuf++];

  }

   private boolean isSpaceChar (int c) { return !(c >= 33 && c <= 126); }

   private int skip()

  {

       int b;

       while ((b = readByte()) != -1 && isSpaceChar(b));

       return b;

  }

   private double nextDouble() { return Double.parseDouble(nextString()); }

   private char nextChar()

  {

       int b = readByte();

       if (b == -1)

           throw new InputMismatchException();

       else

           return (char)b;

  }

   private String nextString()

  {

       int b = skip();

       if (b == -1) throw new InputMismatchException();

       StringBuilder sb = new StringBuilder();

       while (!(isSpaceChar(b))) // when nextline, (isSpaceChae(b) && b != ' ')

      {

           sb.appendCodePoint(b);

           b = readByte();

      }

       return sb.toString();

  }

   private char[] nextString(int n)

  {

       char[] buf = new char[n];

       int b = skip(), p = 0;

       while (p < n && !(isSpaceChar(b)))

      {

           buf[p++] = (char)b;

           b = readByte();

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

Page 215: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

      }

       return n == p ? buf : Arrays.copyOf(buf, p);

  }

   private int[] nextArray(int n)

  {

       int[] a = new int[n];

       for (int i = 0; i < n; i++) a[i] = nextInt();

       return a;

  }

   private int nextInt()

  {

       int num = 0, b;

       boolean minus = false;

       while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));

       if (b == -1) throw new InputMismatchException();

       if (b == '-')

      {

           minus = true;

           b = readByte();

      }

       while (true)

      {

           if (b >= '0' && b <= '9')

               num = num * 10 + (b - '0');

           else

               return minus ? -num : num;

           b = readByte();

      }

  }

   private long nextLong()

  {

       long num = 0;

       int b;

       boolean minus = false;

       while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));

       if (b == -1) throw new InputMismatchException();

       if (b == '-')

      {

           minus = true;

           b = readByte();

      }

       while (true)

      {

           if (b >= '0' && b <= '9')

               num = num * 10 + (b - '0');

           else

               return minus ? -num : num;

           b = readByte();

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

Page 216: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

 

c++数学函数

Java-BigInteger

      }

  }

}

139

140

141

//1 三角函数double sin (double);

double cos (double);

double tan (double);

//2 反三角函数double asin (double); //结果介于[-PI/2, PI/2]

double acos (double); //结果介于[0, PI]

double atan (double); //反正切(主值), 结果介于[-PI/2, PI/2]

double atan2 (double, double); //反正切(整圆值), 结果介于[-PI/2, PI/2]

//3 双曲三角函数double sinh (double);

double cosh (double);

double tanh (double);

//4 指数与对数double exp (double);

double pow (double, double);

double sqrt (double);

double log (double);  //以e为底的对数double log10 (double);

//c++中自然对数函数:log(N)  

//以10为底:log10(N)但没有以2为底的函数但是可以用换底公式解决//log2(N)=log10(N)/log10(2)

//5 取整double ceil (double); 取上整double floor (double); 取下整//6 绝对值double fabs (double);

//7 标准化浮点数double frexp (double f, int *p);  

//标准化浮点数, f = x * 2^p, 已知f求x, p ( x介于[0.5, 1] )

double ldexp (double x, int p);  

//与frexp相反, 已知x, p求f

//8 取整与取余double modf (double, double*); //将参数的整数部分通过指针回传, 返回小数部分double fmod (double, double);   //返回两参数相除的余数//9 平方根double sqrt(double)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

import java.math.BigInteger;  

import java.util.*;  

 

public class Main  

1

2

3

4

Page 217: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

{  

   public static void main(String args[])  

  {  

       Scanner cin = new Scanner(System.in);

       

       //读到EOF

       while(cin.hasNext()){}

       //读入BigInteger

       BigInteger a = cin.nextBigInteger();

       

       //构造方法        //将十进制字符串转化为BigInteger

       //public BigInteger(String val)

       BigInteger b = new BigInteger("3");

       //byte范围-128到+127 8为2进制数 c为767(1011111111)        //public BigInteger(byte[] val)

       byte[] bt = new byte[]{2,-1};

       BigInteger c = new BigInteger(bt);

       //将radix进制的字符串转化为BigInteger

       //public BigInteger(String val, int radix)

       BigInteger d = new BigInteger("3", 2);

       //随机生成 0到2的numBits次方 -1的随机数        //public BigInteger(int numBits, Random rnd)

       BigInteger e = new BigInteger(10, new Random());

       //signum为符号位 1为正 0为0 -1为负        //public BigInteger(int signum, byte[] magnitude)

       BigInteger f = new BigInteger(-1, bt);

       //随机生成一个 长度为bitLength的 可能性大于(1-1/(2的certainty次方))是素数 的数        //public BigInteger(int bitLength, int certainty, Random rnd)

       BigInteger g = new BigInteger(10, 1, new Random());

       

       //常量        //0

       //public static final BigInteger ZERO

       a = BigInteger.ZERO;

       //1

       //public static final BigInteger ONE

       a = BigInteger.ONE;

       //10

       //public static final BigInteger TEN

       a = BigInteger.TEN;

       

       //静态方法        //随机生成一个 长度为bitLength的可能是素数的数        //public static BigInteger probablePrime(int bitLength, Random rnd)

       BigInteger.probablePrime(10, new Random());

       //值等于val的值        //public static BigInteger valueOf(long val)

       BigInteger.valueOf(10);

       

       //加法a+b

       //public BigInteger add(BigInteger val)

       a.add(b);

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

Page 218: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       //减法a-b

       //public BigInteger subtract(BigInteger val)

       a.subtract(b);

       //乘法a*b

       //public BigInteger subtract(BigInteger val)

       a.multiply(b);

       //除法a/b

       //public BigInteger divide(BigInteger val)

       a.divide(b);

       //取模a%b b需大于0 5mod3=2 -5mod3=1

       //public BigInteger mod(BigInteger m)

       a.mod(b);

       //求余 5rem3=2 -5rem3=-2 5rem-3=2 -5rem-3=-2

       //public BigInteger remainder(BigInteger val)

       a.remainder(b);

       //[0]为a/b [1]为a%b

       //public BigInteger[] divideAndRemainder(BigInteger val)

       a.divideAndRemainder(b);

       

       //a==b?

       //public boolean equals(Object x)

       a.equals(b);

       //a的正负 正为1 0为0 负为-1

       //public int signum()

       a.signum();

       //绝对值|a|

       //public BigInteger abs()

       a.abs();

       //比较a>b返回1 a==b返回0 a<b返回-1

       //public BigInteger andNot(BigInteger val)

       a.compareTo(b);

       //相反数-a

       //public BigInteger negate()

       a.negate();

       //max(a,b)

       //public BigInteger max(BigInteger val)

       a.max(b);

       //min(a,b)

       //public BigInteger min(BigInteger val)

       a.min(b);

       //次方a的3次方        //public BigInteger pow(int exponent)

       a.pow(3);

       //a的-1次方 %b

       //public BigInteger modInverse(BigInteger m)

       a.modInverse(b);

       //a的b次方 %c

       //public BigInteger modPow(BigInteger exponent,BigInteger m)

       a.modPow(b, c);

       

       //~a

       //public BigInteger not()

       a.not();

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

Page 219: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       //a^b

       //public BigInteger xor(BigInteger val)

       a.xor(b);

       //a|b

       //public BigInteger or(BigInteger val)

       a.or(b);

       //a&b

       //public BigInteger divide(BigInteger val)

       a.and(b);

       //a左移n位 (a << n)

       //public BigInteger shiftLeft(int n)

       a.shiftLeft(10);

       //a右移n位 (a >> n)

       //public BigInteger shiftRight(int n)

       a.shiftRight(10);

       //a&(~b)

       //public BigInteger andNot(BigInteger val)

       a.andNot(b);

       //二进制形式中把第n位二进制设为0 (a & ~(1<<n))

       //public BigInteger clearBit(int n)

       a.clearBit(10);

       //二进制形式中把第n位二进制设为1 (a | (1<<n))

       //public BigInteger setBit(int n)

       a.setBit(10);

       //二进制形式中第n位二进制是否为1 (a & (1<<n)) != 0)

       //public boolean testBit(int n)

       a.testBit(10);

       //二进制形式中把第n位二进制翻转 (a ^ (1<<n))

       //public BigInteger flipBit(int n)

       a.flipBit(10);

       //二进制形式中最低位1后面0的个数 (a == 0? -1 : log2(a & -a))

       //public int getLowestSetBit()

       a.getLowestSetBit();

       //二进制形式中与符号不同的位的数量 7为3 -7为2

       //public int bitCount()

       a.bitCount();

       //二进制形式中不包括符号位的长度        //public int bitLength()

       a.bitLength();

       

       //a和b的最大公约数        //public BigInteger gcd(BigInteger val)

       a.gcd(b);

       //a可能为素数返回true a一定为合数返回false 素数可能性大于(1-1/(2的certainty次方))

       //public boolean isProbablePrime(int certainty)

       a.isProbablePrime(10);

       //大于a的可能为素数的第一个整数。        //public BigInteger nextProbablePrime()

       a.nextProbablePrime();

       //a的哈希码        //public int hashCode()

       a.hashCode();

       

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

Page 220: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       //a的二进制补码形式        //public byte[] toByteArray()

       a.toByteArray();

       //a的十进制字符串形式        //public String toString()

       a.toString();

       //a的radix进制字符串形式        //public String toString(int radix)

       a.toString(2);

       //将a转换为int

       //public int intValue()

       a.intValue();

       //将a转换为long

       //public long longValue()

       a.longValue();

       //将a转换为float

       //public float floatValue()

       a.floatValue();

       //将a转换为double

       //public double doubleValue()

       a.doubleValue();

       

       //JAVA 1.8

       a.byteValueExact();

       a.intValueExact();

       a.longValueExact();

       a.shortValueExact();

       

       //从类 java.lang.Number 继承的方法        //将a转换为short

       //public short shortValue()

       a.shortValue();

       //将a转换为byte

       //public byte byteValue()

       a.byteValue();

       

       //从类 java.lang.Object 继承的方法        //public final Class<?> getClass()

       a.getClass();

       //public final void notify()

       a.notify();

       //public final void notifyAll()

       a.notifyAll();

       try {

           //public final void wait() throws InterruptedException

           a.wait();

           //public final void wait(long timeout) throws InterruptedException

           a.wait(10);

           //public final void wait(long timeout, int nanos) throws

InterruptedException

           a.wait(10, 10);

      } catch (Exception exception) {

      }

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

Page 221: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

Java-Decimal

  }  

}  

216

217

218

//构造 BigDecimal 对象常用以下方法:

BigDecimal BigDecimal(double d); //不允许使用BigDecimal BigDecimal(String s); //常用,推荐使用static BigDecimal valueOf(double d); //常用,推荐使用

/*

其中,

1. double 参数的构造方法,不允许使用!!!!因为它不能精确的得到相应的值;

2. String 构造方法是完全可预知的: 写入 new BigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的0.1; 因此,通常建议优先使用 String 构造方法;

3. 静态方法 valueOf(double val) 内部实现,仍是将 double 类型转为 String 类型; 这通常是将 double(或float)转化为 BigDecimal 的首选方法;

*/

//构造函数测试代码

public static void main(String[] args) {

double d1 = 0.10334;

double d2 = 1234.0;

System.out.println("new BigDecimal("+d1+")=" + new BigDecimal(d1)); //此种方式绝对不允许!!!!!

System.out.println("new BigDecimal("+d2+")=" + new BigDecimal(d2)); //此种方式绝对不允许!!!!!

System.out.println("");

System.out.println("new BigDecimal(String.valueOf("+d1+"))=" + new

BigDecimal(String.valueOf(d1)));

System.out.println("new BigDecimal(String.valueOf("+d2+"))=" + new

BigDecimal(String.valueOf(d2)));

System.out.println("");

System.out.println("new BigDecimal(String.valueOf("+d1+"))=" + new

BigDecimal(Double.toString(d1)));

System.out.println("new BigDecimal(String.valueOf("+d2+"))=" + new

BigDecimal(Double.toString(d2)));

System.out.println("");

System.out.println("BigDecimal.valueOf("+d1+")=" + BigDecimal.valueOf(d1));

System.out.println("BigDecimal.valueOf("+d2+")=" + BigDecimal.valueOf(d2));

System.out.println("");

BigDecimal b1 = BigDecimal.valueOf(1);

BigDecimal b2 = BigDecimal.valueOf(1.00000);

System.out.println(b1.equals(b2));

System.out.println(b1.compareTo(b2));

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

Page 222: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

//输出如下

new BigDecimal(0.10334)=0.10334000000000000130118138486068346537649631500244140625

new BigDecimal(1234.0)=1234

new BigDecimal(String.valueOf(0.10334))=0.10334

new BigDecimal(String.valueOf(1234.0))=1234.0

new BigDecimal(String.valueOf(0.10334))=0.10334

new BigDecimal(String.valueOf(1234.0))=1234.0

BigDecimal.valueOf(0.10334)=0.10334

BigDecimal.valueOf(1234.0)=1234.0

false

0

//BigDecimal 类的 valueOf()方法源码public static BigDecimal valueOf(double val) {

return new BigDecimal(Double.toString(val));

}

//BigDecimal类的几个常用方法/**

* 求余数 * 返回值为 (this % divisor) 的 BigDecimal

*/

BigDecimal remainder(BigDecimal divisor);

/**

* 求相反数 * 返回值是 (-this) 的 BigDecimal

*/

BigDecimal negate();

/**

* 将此 BigDecimal 与指定的 BigDecimal 比较 * 根据此方法,值相等但具有不同标度的两个 BigDecimal 对象(如,2.0 和 2.00)被认为是相等的;

* 相对六个 boolean 比较运算符 (<, ==, >, >=, !=, <=) 中每一个运算符的各个方法,优先提供此方法;

* 建议使用以下语句执行上述比较:(x.compareTo(y) <op> 0), 其中 <op> 是六个比较运算符之一;

*

* 指定者:接口 Comparable<BigDecimal> 中的 compareTo

* 返回:当此 BigDecimal 在数字上小于、等于或大于 val 时,返回 -1、0 或 1

*/

int compareTo(BigDecimal val);

//提供精确的浮点数运算(包括加、减、乘、除、四舍五入)的工具类源码package com.util;

import java.math.BigDecimal;

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

Page 223: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

/**

* 提供精确的浮点数运算(包括加、减、乘、除、四舍五入)工具类 */

public class ArithUtil {

// 除法运算默认精度 private static final int DEF_DIV_SCALE = 10;

private ArithUtil() {

}

/**

* 精确加法 */

public static double add(double value1, double value2) {

BigDecimal b1 = BigDecimal.valueOf(value1);

BigDecimal b2 = BigDecimal.valueOf(value2);

return b1.add(b2).doubleValue();

}

/**

* 精确减法 */

public static double sub(double value1, double value2) {

BigDecimal b1 = BigDecimal.valueOf(value1);

BigDecimal b2 = BigDecimal.valueOf(value2);

return b1.subtract(b2).doubleValue();

}

/**

* 精确乘法 */

public static double mul(double value1, double value2) {

BigDecimal b1 = BigDecimal.valueOf(value1);

BigDecimal b2 = BigDecimal.valueOf(value2);

return b1.multiply(b2).doubleValue();

}

/**

* 精确除法 使用默认精度 */

public static double div(double value1, double value2) throws

IllegalAccessException {

return div(value1, value2, DEF_DIV_SCALE);

}

/**

* 精确除法 * @param scale 精度 */

public static double div(double value1, double value2, int scale) throws

IllegalAccessException {

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

Page 224: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

Java-奇淫巧技

if(scale < 0) {

throw new IllegalAccessException("精确度不能小于0");

}

BigDecimal b1 = BigDecimal.valueOf(value1);

BigDecimal b2 = BigDecimal.valueOf(value2);

// return b1.divide(b2, scale).doubleValue();

return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();

}

/**

* 四舍五入 * @param scale 小数点后保留几位 */

public static double round(double v, int scale) throws IllegalAccessException

{

return div(v, 1, scale);

}

/**

* 比较大小 */

public static boolean equalTo(BigDecimal b1, BigDecimal b2) {

if(b1 == null || b2 == null) {

return false;

}

return 0 == b1.compareTo(b2);

}

}

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

//1. 输入:

//格式为:Scanner cin = new Scanner (new BufferedInputStream(System.in));

//或者Scanner cin = new Scanner (System.in);

//例程:

import java.io.*;

import java.math.*;

import java.util.*;

import java.text.*;

public class Main

{

   public static void main(String[] args)

  {

       Scanner cin = new Scanner (new BufferedInputStream(System.in));

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

Page 225: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       int a; double b; BigInteger c; String st;

       a = cin.nextInt(); b = cin.nextDouble(); c = cin.nextBigInteger(); d =

cin.nextLine();

// 每种类型都有相应的输入函数.

  }

}

//2. 输出

//函数:System.out.print(); System.out.println(); System.out.printf();

System.out.print();   // cout << …;

System.out.println(); // cout << … << endl;

System.out.printf();  // 与C中的printf用法类似.

//例程:

import java.io.*;

import java.math.*;

import java.util.*;

import java.text.*;

public class Main

{

   public static void main(String[] args)

  {

       Scanner cin = new Scanner (new BufferedInputStream(System.in));

       int a; double b;

       a = 12345; b = 1.234567;

       System.out.println(a + " " + b);

       System.out.printf("%d %10.5f\n", a, b);

// 输入b为字宽为10,右对齐,保留小数点后5位,四舍五入.

  }

}

//规格化的输出:

//函数:

// 这里0指一位数字,#指除0以外的数字(如果是0,则不显示),四舍五入.

   DecimalFormat fd = new DecimalFormat("#.00#");

   DecimalFormat gd = new DecimalFormat("0.000");

   System.out.println("x =" + fd.format(x));

   System.out.println("x =" + gd.format(x));

//3. 字符串处理

//java中字符串String是不可以修改的,要修改只能转换为字符数组.

import java.io.*;

import java.math.*;

import java.util.*;

import java.text.*;

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

Page 226: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

public class Main

{

   public static void main(String[] args)

  {

       int i;

       Scanner cin = new Scanner (new BufferedInputStream(System.in));

       String st = "abcdefg";

       System.out.println(st.charAt(0)); // st.charAt(i)就相当于st[i].

       char [] ch;

       ch = st.toCharArray(); // 字符串转换为字符数组.

       for (i = 0; i < ch.length; i++) ch[i] += 1;

       System.out.println(ch); // 输入为“bcdefgh”.

if (st.startsWith("a")) //如果字符串以'0'开头.

      {

           st = st.substring(1); // 则从第1位开始copy(开头为第0位).

      }

  }

}

//5. 进制转换

函数:

String st = Integer.toString(num, base);

// 把num当做10进制的数转成base进制的st(base <= 35).

int num = Integer.parseInt(st, base);

// 把st当做base进制,转成10进制的int(parseInt有两个参数,第一个为要转的字符串,第二个为说明是什么进制).  

BigInter m = new BigInteger(st, base);

// st是字符串,base是st的进制.

//1.如果要将一个大数以2进制形式读入 可以使用cin.nextBigInteger(2);

//2.如果要将一个大数转换成其他进制形式的字符串 使用cin.toString(2);

//将它转换成2进制表示的字符串

//例程:POJ 2305

import java.io.*;

import java.util.*;

import java.math.*;

public class Main

{

   public static void main(String[] args)

  {

       int b;

       BigInteger p,m,ans;

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

Page 227: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       String str ;

       Scanner cin = new Scanner (new BufferedInputStream(System.in));

       while(cin.hasNext())

      {

           b=cin.nextInt();

           if(b==0) break;

           p=cin.nextBigInteger(b);

           m=cin.nextBigInteger(b);

           ans=p.mod(m);

           str=ans.toString(b);

           System.out.println(str);

      }

  }

}

//6. 排序

//函数:Arrays.sort();import java.io.*;

import java.math.*;

import java.util.*;

import java.text.*;

public class Main

{

   public static void main(String[] args)

  {

       Scanner cin = new Scanner (new BufferedInputStream(System.in));

       int n = cin.nextInt();

       int a[] = new int [n];

       for (int i = 0; i < n; i++) a[i] = cin.nextInt();

       Arrays.sort(a);

       for (int i = 0; i < n; i++) System.out.print(a[i] + " ");

  }

}

//7. 结构体排序:/*

例子:一个结构体有两个元素String x,int y,排序,如果x相等y升序,否者x升序。

一、Comparator

强行对某个对象collection进行整体排序的比较函数,可以将Comparator传递给Collections.sort或Arrays.sort。

接口方法:这里也给出了两种方法*/

import java.util.*;

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

Page 228: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

class structSort {

   String x;

   int y;

}

class cmp implements Comparator<structSort> {

   public int compare(structSort o1, structSort o2) {

       if (o1.x.compareTo(o2.x) == 0) { //这个相当于c/c++中strcmp(o1.x , o2,x)

           return o1.y - o2.y;

      }

       return o1.x.compareTo(o2.x);

  }

}

public class Main {

   public static void main(String[] args) {

       Comparator<structSort> comparator = new Comparator<structSort>() {

           public int compare(structSort o1, structSort o2) {

               if (o1.x.compareTo(o2.x) == 0) {

                   return o1.y - o2.y;

              }

               return o1.x.compareTo(o2.x);

          }

      };

       Scanner cin = new Scanner(System.in);

       int n = cin.nextInt();

       structSort a[] = new structSort[10];

       for (int i = 0; i < n; i++) {

           a[i] = new structSort();

           a[i].x = cin.next();

           a[i].y = cin.nextInt();

      }

       Arrays.sort(a, 0, n, comparator); //这个直接使用Comparator

       Arrays.sort(a, 0, n, new cmp()); //这个实现Comparator,就就跟c++中的sort函数调用就差不多了

       for (int i = 0; i < n; i++) {

           System.out.println(a[i].x + " " + a[i].y);

      }

  }

}

/*

二、Comparable

强行对实现它的每个类的对象进行整体排序,实现此接口的对象列表(和数组)可以通过Collections.sort或Arrays.sort进行自动排序。就是输入完了直接就默认排序了,

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

Page 229: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

接口方法:*/

import java.util.*;

class structSort implements Comparable<structSort> {

   String x;

   int y;

   public int compareTo(structSort o1) {

       if (this.x.compareTo(o1.x) == 0) {

           return this.y - o1.y;

      }

       return this.x.compareTo(o1.x);

  }

}

public class Main {

   public static void main(String[] args) {

       Scanner cin = new Scanner(System.in);

       int n = cin.nextInt();

       structSort a[] = new structSort[10];

       for (int i = 0; i < n; i++) {

           a[i] = new structSort();

           a[i].x = cin.next();

           a[i].y = cin.nextInt();

      }

       Arrays.sort(a, 0, n);

       for (int i = 0; i < n; i++) {

           System.out.println(a[i].x + " " + a[i].y);

      }

  }

}

//acm中Java的应用//下面说一下ACM-ICPC队员初用Java编程所遇到的一些问题:  

//1. 基本输入输出:  

//(1)

//JDK 1.5.0 新增的Scanner类为输入提供了良好的基础,简直就是为ACM-ICPC而设的。

读一个整数: int n = cin.nextInt();          

相当于      scanf("%d", &n);  

或  cin >> n;

读一个字符串: String s = cin.next();          

相当于     scanf("%s", s);    

或 cin >> s;

读一个浮点数: double t = cin.nextDouble();    

相当于     scanf("%lf", &t);

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

Page 230: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

或 cin >> t;

读一整行:  String s = cin.nextLine();    

相当于     gets(s);    

或 cin.getline(...);

//判断是否有下一个输入可以用

cin.hasNext()

cin.hasNextInt()

cin.hasNextDouble()

//(2)

//输出一般可以直接用

System.out.print() 和 System.out.println()

//前者不输出换行,而后者输出。

//比如:System.out.println(n);    // n 为 int 型

//同一行输出多个整数可以用

System.out.println(new Integer(n).toString() + " " + new Integer(m).toString());

//也可重新定义:

static PrintWriter cout = new PrintWriter(new BufferedOutputStream(System.out));

cout.println(n);

//(3)

//对于输出浮点数保留几位小数的问题,可以使用DecimalFormat类,

import java.text.*;

DecimalFormat f = new DecimalFormat("#.00#");

DecimalFormat g = new DecimalFormat("0.000");

double a = 123.45678, b = 0.12;

System.out.println(f.format(a));

System.out.println(f.format(b));

System.out.println(g.format(b));

//这里0指一位数字,#指除0以外的数字。

//2. 字符串

//String 类用来存储字符串,可以用charAt方法来取出其中某一字节,计数从0开始:

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

Page 231: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

String a = "Hello";      // a.charAt(1) = ’e’

//用substring方法可得到子串,如上例

System.out.println(a.substring(0, 4))      // output "Hell"

//注意第2个参数位置上的字符不包括进来。这样做使得 s.substring(a, b) 总是有 b-a个字符。

//字符串连接可以直接用 + 号,如

String a = "Hello";

String b = "world";

System.out.println(a + ", " + b + "!");      // output "Hello, world!"

//如想直接将字符串中的某字节改变,可以使用另外的StringBuffer类。

//3. 调用递归(或其他动态方法)

//在主类中 main 方法必须是 public static void 的//在 main 中调用非static类时会有警告信息,可以先建立对象,然后通过对象调用方法:

public class Main

{

    ...

     void dfs(int a)

    {

         if (...) return;

        ...

         dfs(a+1);

    }

   

     public static void main(String args[])

    {

        ...

         Main e = new Main();

         e.dfs(0);

        ...

    }

}

//5. 其他注意的事项

/*

(1) Java 是面向对象的语言,思考方法需要变换一下,里面的函数统称为方法,不要搞错。

(2) Java 里的数组有些变动,多维数组的内部其实都是指针,所以Java不支持fill多维数组。

     数组定义后必须初始化,如 int[] a = new int[100];

(3) 布尔类型为 boolean,只有true和false二值,在 if (...) / while (...) 等语句的条件中必须为boolean类型。

     在C/C++中的 if (n % 2) ... 在Java中无法编译通过。

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

Page 232: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

(4) 下面在java.util包里Arrays类的几个方法可替代C/C++里的memset、qsort/sort 和 bsearch:

*/

Arrays.fill()

Arrays.sort()

Arrays.binarySearch()

//Java进制转换~集锦//由于Unicode兼容ASCII(0~255),因此,上面得到的Unicode就是ASCII。//java中进行二进制,八进制,十六进制,十进制间进行相互转换      

Integer.toHexString(int i)

//十进制转成十六进制

Integer.toOctalString(int i)

//十进制转成八进制

Integer.toBinaryString(int i)

//十进制转成二进制

Integer.valueOf("FFFF",16).toString()

//十六进制转成十进制

Integer.valueOf("876",8).toString()

//八进制转成十进制

Integer.valueOf("0101",2).toString()

//二进制转十进制//至于转换成二进制或其他进制,Java API提供了方便函数,你可以查Java的API手册。

//以字符a的ASCII为例:

int i = 'a';

String iBin = Integer.toBinaryString(i); //二进制

String iHex = Integer.toHexString(i); //十六进制

String iOct = Integer.toOctalString(i); //八进制

String iWoKao = Integer.toString(i,3); //三进制或任何你想要的35进制以下的进制

//有什么方法可以直接将2,8,16进制直接转换为10进制的吗?

java.lang.Integer类 parseInt(String s, int radix)

//使用第二个参数指定的基数,将字符串参数解析为有符号的整数。

examples from jdk:

parseInt("0", 10) returns 0

parseInt("473", 10) returns 473

parseInt("-0", 10) returns 0

parseInt("-FF", 16) returns -255

parseInt("1100110", 2) returns 102

parseInt("2147483647", 10) returns 2147483647

parseInt("-2147483648", 10) returns -2147483648

parseInt("2147483648", 10) throws a NumberFormatException

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

Page 233: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

parseInt("99", 8) throws a NumberFormatException

parseInt("Kona", 10) throws a NumberFormatException

parseInt("Kona", 27) returns 411787

//进制转换如何写(二,八,十六)不用算法

Integer.toBinaryString

Integer.toOctalString

Integer.toHexString

//例一:

public class Test{

public static void main(String args[]){

  int i=100;

  String binStr=Integer.toBinaryString(i);

  String otcStr=Integer.toOctalString(i);

  String hexStr=Integer.toHexString(i);

  System.out.println(binStr);

//例二:

public classTestStringFormat

{

public static void main(String[] args)

{

if (args.length == 0)

{

System.out.println("usage: javaTestStringFormat <a number>");

System.exit(0);

}

Integer factor =Integer.valueOf(args[0]);

String s;

s =String.format("%d", factor);

System.out.println(s);

s = String.format("%x", factor);

System.out.println(s);

s = String.format("%o", factor);

System.out.println(s);

}

}

//各种数字类型转换成字符串型:

String s = String.valueOf( value); // 其中 value 为任意一种数字类型。字符串型转换成各种数字类型:String s = "169";

byte b = Byte.parseByte( s );

short t = Short.parseShort( s );

int i = Integer.parseInt( s );

long l = Long.parseLong( s );

Float f = Float.parseFloat( s );

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466

467

468

469

470

471

472

473

474

475

476

477

478

479

480

481

482

483

484

485

486

487

488

489

490

491

Page 234: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

最长递增子序列

Double d = Double.parseDouble( s );

//数字类型与数字类对象之间的转换:

byte b = 169;

Byte bo = new Byte( b );

b = bo.byteValue();

short t = 169;

Short to = new Short( t );

t = to.shortValue();

int i = 169;

b = bo.byteValue();

short t = 169;

Short to = new Short( t );

t = to.shortValue();

int i = 169;

Integer io = new Integer( i );

i = io.intValue();

long l = 169;

Long lo = new Long( l );

l = lo.longValue();

float f = 169f;

Float fo = new Float( f );

f = fo.floatValue();

double d = 169f;

Double dObj = new Double( d );

d = dObj.doubleValue();

492

493

494

495

496

497

498

499

500

501

502

503

504

505

506

507

508

509

510

511

512

513

514

515

516

517

518

519

// nlogn 解法 dp[i]表示 以i结尾的LIS dp2[i] 表示以i开头的LIS

inline void LIS()

{

int len = 0; brr[1] = 0;

for (int i = 1; i <= n; ++i)

{

if (arr[i] == 0) continue;

int pos = lower_bound(brr + 1, brr + 1 + len, arr[i]) - brr;

if (pos > len) ++len;  

dp[i] = pos; brr[pos] = arr[i];

}

m = len; len = 0; brr[1] = 0;

for (int i = n; i >= 1; --i)

{

if (arr[i] == 0) continue;

int pos = lower_bound(brr + 1, brr + 1 + len, -arr[i]) - brr;

if (pos > len) ++len;

dp2[i] = pos; brr[pos] = -arr[i];

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

Page 235: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

最长公共子序列

//我们可以从最后一位来看,存在子串 A 和子串 B ,如果子串 A 的最后一个元素与子串 B

//的最后一个元素相等,那么 此时的LCS = 子串 A 长度减一 和子串 B 长度减一的LCS + 1

//如果不相等 ,那么 此时的LCS = 子串 A 长度减一 与子串 B 或者子串 A 与子串 B 长度减一//的最大值

//最长公共子序列

#include <bits/stdc++.h>

using namespace std;

const int maxn   = 1e3 * 5 + 5;

int dp[maxn][maxn];

int main()

{

string a, b;

cin >> a >> b;

int i, j;

int len = a.size();

memset(dp, 0, sizeof(dp));

for (i = 0; i < len; i++)

{

if (i)

{

dp[0][i] = dp[0][i - 1];

dp[i][0] = dp[i - 1][0];

}

if (a[0] == b[i])

dp[0][i] = 1;

if (b[0] == a[i])

dp[i][0] = 1;

}

for (i = 1; i < len; i++)

{

for (j = 1; j < len; j++)

{

if (a[i] == b[j])

dp[i][j] = dp[i - 1][j - 1] + 1;

else

dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]);

}

}

cout << dp[len - 1][len - 1] << endl;  

}

//求得并输出其中一个最长公共子序列

#include <bits/stdc++.h>

using namespace std;

const int maxn   = 1e3 * 5 + 5;

int dp[maxn][maxn];

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

Page 236: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

int main()

{

string a, b;

cin >> a >> b;

int i, j;

int len = a.size();

memset(dp, 0, sizeof(dp));

for (i = 0; i < len; i++)

{

if (i)

{

dp[0][i] = dp[0][i - 1];

dp[i][0] = dp[i - 1][0];

}

if (a[0] == b[i])

dp[0][i] = 1;

if (b[0] == a[i])

dp[i][0] = 1;

}

for (i = 1; i < len; i++)

{

for (j = 1; j < len; j++)

{

if (a[i] == b[j])

dp[i][j] = dp[i - 1][j - 1] + 1;

else

dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]);

}

}

i = len - 1, j = len - 1;

while (i && j)          //输出其中一个LCS

{

if (a[i] == b[j])

{

cout << a[i] << endl;

i--;

j--;

}

else

{

if (dp[i - 1][j] >= dp[i][j - 1])

i--;

else

j--;

}

}

}

//nlogn解法   仅限于两个串中每个数都不同,将arr[]中变为brr[]中的下标,然后对arr[]求最长上升子序列

#include <bits/stdc++.h>

using namespace std;

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

Page 237: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

#define N 62510

#define INF 0x3f3f3f3f

int t, n, p, q;

int arr[N], brr[N];

int vis[N], a[N];

inline int lowbit(int x)

{

return x & (-x);

}

inline void update(int x, int val)

{

for (int i = x; i <= n * n; i += lowbit(i))

a[i] = max(a[i], val);

}

inline int query(int x)

{

int res = 0;

for (int i = x; i > 0; i -= lowbit(i))

res = max(res, a[i]);

return res;

}

inline void Run()

{

scanf("%d", &t);

for (int kase = 1; kase <= t; ++kase)

{

printf("Case %d: ", kase);

scanf("%d%d%d", &n, &p, &q); ++p, ++q;

for (int i = 1; i <= p; ++i) scanf("%d", arr + i);

memset(vis, 0x3f, sizeof vis);

for (int i = 1; i <= q; ++i)

{

scanf("%d", brr + i);

vis[brr[i]] = i;

}

for (int i = 1; i <= p; ++i) arr[i] = vis[arr[i]];

memset(a, 0, sizeof a);

for (int i = 1; i <= p; ++i)

{

if (arr[i] == INF) continue;

//printf("%d %d\n", i, arr[i]);

update(arr[i], query(arr[i] - 1) + 1);

}

printf("%d\n", query(n * n));

}

}

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

Page 238: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

最长公共递增子序列

int main()

{

#ifdef LOCAL

freopen("Test.in", "r", stdin);

#endif

Run();

return 0;

}

157

158

159

160

161

162

163

164

165

/*

* 最长公共递增子序列 O(n^2)

* f记录路径,DP记录长度, 用a对b扫描,逐步最优化。 */

const int N = 1010;

int f[N][N], dp[N];

int gcis(int a[], int la, int b[], int lb, int ans[])

{   // a[1...la], b[1...lb]

   int i, j, k, mx;

   memset(f, 0, sizeof(f));

   memset(dp, 0, sizeof(dp));

   for (i = 1; i <= la; i++)

  {

       memcpy(f[i], f[i-1], sizeof(f[0]));

       for (k = 0, j = 1; j <= lb; j++)

      {

           if (b[j - 1] < a[i - 1] && dp[j] > dp[k])

          {

               k = j;

          }

           if (b[j - 1] == a[i - 1] && dp[k] + 1 > dp[j])

          {

               dp[j] = dp[k] + 1,

               f[i][j] = i * (lb + 1) + k;

          }

      }

  }

   for (mx = 0, i = 1; i <= lb; i++)

  {

       if (dp[i] > dp[mx])

      {

           mx = i;

      }

  }

   for (i = la * lb + la + mx, j = dp[mx]; j; i = f[i / (lb + 1)][i % (lb + 1)],

j--)

  {

       ans[j - 1] = b[i % (lb + 1) - 1];

  }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

Page 239: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

机器工作调度

   return dp[mx];

}

41

42

/*

机器工作调度

2台机器,n件任务,必须先在S1上做,再在S2上做.

任务之间先做后做任意.求最早的完工时间.

这是一个经典问题: 2台机器的情况下有多项式算法(Johnson算法),3台或以上的机器是NP-hard算法。

Johnson算法:

(1)把作业按工序加工时间分成两个子集,第一个集合中在S1上做的时间比在S2上少,其它的作业放到第二个集合;

先完成第一个集合里面的作业,再完成第二个集合里的作业.

(2)对于第一个集合,其中的作业顺序是按在S1上的时间的不减排列;

对于第二个集合, 其中的作业顺序是按在S2上的时间的不增排列.

*/

const int MAXN = 5e4 + 5;

struct task

{

   int a;

   int b;

} TaskA[MAXN], TaskB[MAXN];

bool cmpA(task a, task b)

{

   return a.a <= b.a;

}

bool cmpB(task a, task b)

{

   return a.b >= b.b;

}

int main(int argc, const char * argv[])

{

   int N;

   cin >> N;

   int a, b;

   int posA = 0, posB = 0;

   int sumA = 0, sumB = 0;

   for (int i = 0; i < N; i++)

  {

       scanf("%d %d", &a, &b);

       if (a < b)

      {

           TaskA[posA].a = a;

           TaskA[posA++].b = b;

           sumA += b;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

Page 240: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

最少找硬币问题

      }

       else

      {

           TaskB[posB].a = a;

           TaskB[posB++].b = b;

           sumB += a;

      }

  }

   sort(TaskA, TaskA + posA, cmpA);

   sort(TaskB, TaskB + posB, cmpB);

   for (int i = 0; i < posB; i++)

  {

       TaskA[posA++] = TaskB[i];

  }

   int ans = TaskA[0].a + TaskA[0].b;

   int sum = TaskA[0].a;

   for (int i = 1; i < posA; i++)

  {

       sum += TaskA[i].a;

       ans = sum < ans ? ans + TaskA[i].b : sum + TaskA[i].b;

  }

   cout << ans << '\n';

   return 0;

}

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

//最少找硬币问题

/*

* 贪心策略-深度搜索 */

int value[7] = {100, 50, 20, 10, 5, 2, 1};

int count[7];   // count[i]:value[i]硬币的个数int res[7];

bool flag;

void DFS(int total, int p);

int main()

{

   int pay = 0;

   scanf("%d", &pay);

   //...

   flag = false;   // 标识是否已经找到结果    for (int i = 0; i < 7; ++i)

  {

       res[i] = 0;

  }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

Page 241: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

棋盘分割

   DFS(pay, 0);    // pay为要找的钱数    if (flag)

  {

       printf("Accept\n%d", res[0]);

       for (int i = 1; i < 7; ++i)

      {

           printf(" %d", res[i]);

      }

       printf("\n");

  }

   else

  {

       printf("Refuse\n");     // 无法正好找钱   }

}

void DFS(int total, int p)

{

   if (flag)

  {

       return ;

  }

   if (p == 7)

  {

       if (total == 0)

      {

           flag = true;

      }

       return ;

  }

   int i, max = total / value[p];

   if (max > count[p])

  {

       max = count[p];

  }

   for (i = max; i >= 0; --i)

  {

       res[p] = i;

       DFS(total - i * value[p], p + 1);

       if (flag)

           return ;

  }

   return ;

}

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

/*

* 棋盘分割 * 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部

* 分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最

1

2

3

4

5

6

Page 242: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

* 后剩下的矩形棋盘共有n块矩形棋盘。(每次切割都只能沿着棋盘格子的边

* 进行) 原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分 * 值之和。现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋

* 盘总分的均方差最小。 均方差...,其中平均值...,xi为第i块矩形棋盘的 * 总分。请编程对给出的棋盘及 n,求出 O'的最小值。 */

#define min(a, b) ((a) < (b) ? (a) : (b))

const int oo = 10000000;

int map[8][8];

double C[16][8][8][8][8];   // c[k][si][ei][sj][ej]: 对矩阵// map[si...sj][ei...ej]分割成k个矩形(切割k-1刀)的结果double ans;                 // 平均值int n;                      // 分成n块矩形棋盘

void input(void);

void reset(void);

double caluate(int i1, int j1, int i2, int j2);

void dp(int m, int si, int sj, int ei, int ej);

int main()

{

   int m, i, j, k, l;

   while (scanf("%d", &n) != EOF)

  {

       input();

       reset();

       for (m = 1; m <= n; m++)

      {

           for (i = 0; i < 8; i++)

          {

               for (j = 0; j < 8; j++)

              {

                   for (k = 0; k < 8; k++)

                  {

                       for (l = 0; l < 8; l++)

                      {

                           if ((k - i + 1) * (l - j + 1) < m)

                          {

                               C[m][i][j][k][l] = oo;

                          }

                           else

                          {

                               if (m == 1)

                              {

                                   C[m][i][j][k][l] = pow((caluate(i, j, k, l) -

ans), 2);

                              }

                               else

                              {

                                   dp(m, i, j, k, l);

                              }

                          }

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

Page 243: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

                      }

                  }

              }

          }

      }

       printf("%.3lf\n", sqrt(C[n][0][0][7][7] / n));

  }

   return 0;

}

void input()

{

   int i, j;

   double sum = 0;

   for (i = 0; i < 8; i++)

  {

       for (j = 0; j < 8; j++)

      {

           scanf("%d", &map[i][j]);

           sum += map[i][j];

      }

  }

   ans = sum / double(n);  // 平均值}

void reset()

{

   int i, j, k, l, m;

   for (m = 0; m <= n; m++)

  {

       for (i = 0; i < 8; i++)

      {

           for (j = 0; j < 8; j++)

          {

               for (k = 0; k < 8; k++)

              {

                   for (l = 0; l < 8; l++)

                  {

                           C[m][i][j][k][l] = 0;

                  }

              }

          }

      }

  }

   return ;

}

double caluate(int i1, int j1, int i2, int j2)

{

   double sum = 0;

   int i, j;

   for (i = i1; i <= i2; i++)

  {

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

Page 244: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

区间最大频率

       for (j = j1; j <= j2; j++)

      {

           sum += map[i][j];

      }

  }

   return sum;

}

void dp(int m, int si, int sj, int ei, int ej)

{

   int i, j;

   double mins = oo;

   for (j = sj; j < ej; j++)

  {   // 竖刀        mins = min(mins, C[1][si][sj][ei][j] + C[m - 1][si][j + 1][ei][ej]);

       mins = min(mins, C[m - 1][si][sj][ei][j] + C[1][si][j + 1][ei][ej]);

  }

   for (i = si; i < ei; i++)

  {   // 横刀        mins = min(mins, C[1][si][sj][i][ej] + C[m - 1][i + 1][sj][ei][ej]);

       mins = min(mins, C[m - 1][si][sj][i][ej] + C[1][i + 1][sj][ei][ej]);

  }

   C[m][si][sj][ei][ej] = mins;

   return ;

}

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

/*

* 求区间中数出现的最大频率 * 方法一:线段树.

* 先离散化。因为序列是升序,所以先将所有值相同的点缩成一点。这样n规模就缩小了。建立一个数据结构 * 记录缩点的属性:在原序列中的值id,和该值有多少个num比如序列 * 10

* -1 -1 1 1 1 1 3 10 10 10

* 缩点后为:下标 1 2 3 4

*         id -1 1 3 10

*         num 2 4 1 3

* 然后建树,树的属性有区间最大值(也就是频率)和区间总和。 * 接受询问的时候。接受的是原来序列的区间[be,ed]我们先搜索一下两个区间分别在离散化区间后的下标。 * 比如接受[2,3]时候相应下标区间就是[1,2];[3,10]的相应下标区间是[2,4];

* 处理频率的时候,我们发现两个极端,也就是左右两个端点的频率不好处理。因为它们是不完全的频率 * 也就是说有部分不在区间内。但是如果对于完全区间,也就是说左右端点下标值完全在所求区间内。 * 比如上例的[2,3]不好处理。但是如果是[1,6],或是[1,10]就很好处理了,只要像RMQ一样询问区间最大值就可以了。 * 方法二:RMQ.

* 我们可以转化一下问题。将左右端点分开来考虑。 * 现在对于离散后的询问区间我们可以分成3个部分.左端点,中间完全区间,右端点。 * 对于中间完全区间线段树或RMQ都能轻松搞定。只要特判一左右的比较一下就得最后解了。 */

int build(int a, int b);

int query(int index, int a, int b);

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

Page 245: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

const int N = 100010;

struct NODE

{

   int b, e;   // 区间[b, e]

   int l, r;   // 左右子节点下标    int number; // 区间内的最大频率值    int last;   // 以 data[e]结尾且与 data[e]相同的个数:data[e-last+1]...data[e]

} node[N * 2 + 1];

int len, data[N];

int main()

{

   int n;

   while (scanf("%d", &n), n)

  {

       int i, q, a, b;

       scanf("%d", &q);

       for (i = 0; i < n; i++)

      {

           scanf("%d", &data[i]);

      }

       len = 0;    // 下标        build(0, n - 1);

       while (q--)

      {

           scanf("%d%d", &a, &b);

           printf("%d\n", query(0, a - 1, b - 1)); // 输出区间的最大频率值,而非data[]

      }

  }

   return 0;

}

int build(int a, int b) // 建立线段树{

   int temp = len, mid = (a + b) / 2;

   node[temp].b = a, node[temp].e = b;

   len++;

   if (a == b)

  {

       node[temp].number = 1;

       node[temp].last = 1;

       return temp;

  }

   node[temp].l = build(a, mid);

   node[temp].r = build(mid + 1, b);

   int left_c = node[temp].l, right_c = node[temp].r, p, lcount = 0, rcount = 0,

rec, max = 0;

   rec = data[mid];

   p = mid;

   while (p >= a && data[p] == rec)

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

Page 246: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

  {

       p--, lcount++;

  }

   node[left_c].last = lcount;

   rec = data[mid + 1];

   p = mid + 1;

   while (p <= b && data[p] == rec)

  {

       p++, rcount++;

  }

   node[right_c].last = rcount;

   if (data[mid] == data[mid + 1])

  {

       max = lcount + rcount;

  }

   if (node[left_c].number > max)

  {

       max = node[left_c].number;

  }

   if (node[right_c].number > max)

  {

       max = node[right_c].number;

  }

   node[temp].number = max;

   return temp;

}

int query(int index, int a, int b)

{

   int begin = node[index].b;

   int end = node[index].e;

   int mid = (begin + end) / 2;

   if (a == begin && b == end)

  {

       return node[index].number;

  }

   if (a > mid)

  {

       return query(node[index].r, a, b);

  }

   if (b < mid + 1)

  {

       return query(node[index].l, a, b);

  }

   int temp1, temp2, max;

   if (node[index].l > 0)

  {

       temp1 = query(node[index].l, a, mid);

  }

   if (node[index].r > 0)

  {

       temp2 = query(node[index].r, mid + 1, b);

  }

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

Page 247: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

使序列有序的最少交换次数

   max = temp1 > temp2 ? temp1 : temp2;

   if (data[mid] != data[mid + 1])

  {

       return max;

  }

   temp1 = node[node[index].l].last > (mid - a + 1) ? (mid - a + 1) :

node[node[index].l].last;

   temp2 = node[node[index].r].last > (b - mid) ? (b - mid) :

node[node[index].r].last;

   if (max < temp1 + temp2)

  {

       max = temp1 + temp2;

  }

   return max;

}

129

130

131

132

133

134

135

136

137

138

139

140

141

/*

交换相邻两数

如果只是交换相邻两数,那么最少交换次数为该序列的逆序数。*/

//交换任意两数

/*

* 交换任意两数的本质是改变了元素位置, * 故建立元素与其目标状态应放置位置的映射关系 */

int getMinSwaps(vector<int> &A)

{

   // 排序    vector<int> B(A);

   sort(B.begin(), B.end());

   map<int, int> m;

   int len = (int)A.size();

   for (int i = 0; i < len; i++)

  {

       m[B[i]] = i;    // 建立每个元素与其应放位置的映射关系   }

   int loops = 0;      // 循环节个数    vector<bool> flag(len, false);

   // 找出循环节的个数    for (int i = 0; i < len; i++)

  {

       if (!flag[i])

      {

           int j = i;

           while (!flag[j])

          {

               flag[j] = true;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

Page 248: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

               j = m[A[j]];    // 原序列中j位置的元素在有序序列中的位置           }

           loops++;

      }

  }

   return len - loops;

}

vector<int> nums;

int main()

{

   nums.push_back(1);

   nums.push_back(2);

   nums.push_back(4);

   nums.push_back(3);

   nums.push_back(5);

   int res = getMinSwaps(nums);

   cout << res << '\n';

   return 0;

}

//交换任意区间

/*

* 默认目标映射关系是 key 1 => val 1 …… key n => val n

* 如果序列不是 1~n 可以通过 map 建立新的目标映射关系 * 交换任意区间的本质是改变了元素的后继,故建立元素与其初始状态后继的映射关系 */

const int MAXN = 30;

int n;

int vis[MAXN];

int A[MAXN], B[MAXN];

int getMinSwaps()

{

   memset(vis, 0, sizeof(vis));

   for (int i = 1; i <= n; i++)

  {

       B[A[i]] = A[i % n + 1];

  }

   for (int i = 1; i <= n; i++)

  {

       B[i] = (B[i] - 2 + n) % n + 1;

  }

   int cnt = n;

   for (int i = 1; i <= n; i++)

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

Page 249: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

背包相关

  {

       if (vis[i])

      {

           continue;

      }

       vis[i] = 1;

       cnt--;

       for (int j = B[i]; j != i; j = B[j])

      {

           vis[j] = 1;

      }

  }

   return cnt;

}

int main()

{

   cin >> n;

   for (int i = 1; i <= n; i++)

  {

       cin >> A[i];

  }

   int res = getMinSwaps();

   cout << res << '\n';

   return 0;

}

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

//01背包

#include<bits/stdc++.h>    //标准

using namespace std;

const int maxn = 1e3 + 5;

int v[maxn], w[maxn], dp[maxn][maxn];

int main()

{

int n, weight;

while (~scanf("%d%d", &n, &weight))

{

memset(dp, 0, sizeof(dp));

int i, j;

for(i = 1; i <= n; i++)

scanf("%d%d", &v[i], &w[i]);

for (i = 1; i <= n; i++)

{

for (j = weight; j > 0; j--)  

{

dp[i][j] = dp[i - 1][j];    

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

Page 250: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

if(j >= w[i] && dp[i - 1][j - w[i]] + v[i] > dp[i - 1][j])

dp[i][j] = dp[i - 1][j - w[i]] + v[i];

}

}

cout << dp[n][weight] << endl;

}

}

//优化空间

for (i = 1; i <= n; i++)        

{

for (j = weight; j >= w[i]; j--)

{

dp[j] = max(dp[j], dp[j - w[i]] + v[i]);

}

}

////求背包恰好装满时的 价值 不一定是最大价值

#include<bits/stdc++.h>    

using namespace std;

const int maxn = 1e3 + 5;

#define INF 0xc0c0c0c0

int v[maxn], w[maxn], dp[maxn];

int main()

{

int n, weight;

while (~scanf("%d%d", &n, &weight))

{

memset(dp, 0, sizeof(dp));

int i, j;

for(i = 1; i <= n; i++)

scanf("%d%d", &v[i], &w[i]);

memset(dp, 0xc0, sizeof(dp));  

dp[0] = 0;

for (i = 1; i <= n; i++)

{

for (j = weight; j >= w[i]; j--)  

{

dp[j] = max(dp[j], dp[j - w[i]] + v[i]);

}

}

cout << dp[weight] << endl;

}

}

// //求第K 解 或者次优解

#include<bits/stdc++.h>      

using namespace std;

const int maxn = 1e2 + 5;

#define INF 0x3f3f3f3f

int v[maxn], w[maxn], dp[1005][35], a[35], b[35];

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

Page 251: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

int main()

{

int t;

cin >> t;

while (t--)

{

int i, j, l, x, y;

int A, B;

int n, weight, k;

scanf("%d%d%d", &n, &weight, &k);

for(i = 1; i <= n; i++)

scanf("%d", &v[i]);

for (i = 1; i <= n; i++)

scanf("%d", &w[i]);

memset(dp, 0, sizeof(dp));

// memset(a, 0, sizeof(a));

// memset(b, 0, sizeof(b));

for (i = 1; i <= n; i++)

{

for (j = weight; j >= w[i]; j--)  

{

for (l = 1; l <= k; l++)                

{

a[l] = dp[j][l];

b[l] = dp[j - w[i]][l] + v[i];

}

a[l] = -1;

b[l] = -1;

for (l = x = y = 1; (x <= k || y <= k) && l <= k; )

{

if (a[x] > b[y])

{

dp[j][l] = a[x];

x++;

}

else

{

dp[j][l] = b[y];

y++;

}

if (dp[j][l] != dp[j][l - 1])

l++;

}

}

}

cout << dp[weight][k] << endl;

}

}

//分组背包#include<bits/stdc++.h>  

using namespace std;

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

Page 252: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

const int MAX = 0x3f3f3f3f;

const int MIN = 0xc0c0c0c0;

const int maxn = 1e4 + 5;

int v[maxn][maxn], w[maxn][maxn], dp[maxn];

int main()

{

int n, m;

while (scanf("%d%d", &n,&m) && (n || m))

{

int i, j, k;

for (i = 1; i <=n; i++)

{

for (j = 1; j <= m; j++)

{

scanf("%d", &v[i][j]);

w[i][j] = j;

}

}

memset(dp, 0, sizeof(dp));

for (i = 1; i <= n; i++)

for (j = m; j > 0 ; j--)

for (k = 1; k <= m && j >=k; k++)

dp[j] = max(dp[j], dp[j - w[i][k]] + v[i][k]);

cout << dp[m] << endl;

}

}

//输出最佳方案

#include<bits/stdc++.h>

using namespace std;

const int MAX = 0x3f3f3f3f;

const int MIN = 0xc0c0c0c0;

const int maxnn = 1e4 + 5;

const int maxn = 2000 + 5;

int w[maxn], v[maxn], dp[maxn][maxnn], temp[maxn], tag[maxn][maxnn];

int main()

{

int weight

int n;

while (~scanf("%lf%d", &weight, &n))

{

int i, j, k;

for (i = 1; i <= n; i++)

scanf("%d%d", &v[i], &w[i]);

memset(dp, 0, sizeof(dp));

memset(tag, 0, sizeof(tag));

for (i = 1; i <= n; i++)

{

for(j = weight; j > 0; j--)

{

dp[i][j] = dp[i - 1][j];

if (j >= w[i] && (dp[i - 1][j - w[i]] + v[i]) > dp[i - 1][j])

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

Page 253: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

{

dp[i][j] = dp[i - 1][j - w[i]] + v[i];

tag[i][j] = 1;

}

}

}

i = n;

j = weight;

k = 0;

while (i > 0)

{

if(tag[i][j] == 1)

{

temp[k++] = i - 1;

j -= w[i];

}

i--;

}

sort(temp, temp + k);

printf("%d\n", k);

for(i = 0; i < k; i++)

{

if (i)

printf(" ");

printf("%d", temp[i]);

}

if(k) printf("\n");

}

}

//完全背包#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e4 + 5;

int dp[maxn], v[maxn], w[maxn];

int main()

{

int t;

cin >> t;

while (t--)

{

int weight, n;

scanf("%d%d", &weight, &n);

int i, j;

for (i = 1; i <= n; i++)

scanf("%d", &v[i]);

for (i = 1; i <= n ; i++)

scanf("%d", &w[i]);

memset(dp, 0, sizeof(dp));

for (i = 1; i <=n; i++)

{

for(j = v[i]; j <= weight; j++)

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

Page 254: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

dp[j] = max(dp[j], dp[j - w[i]] + v[i]);

}

cout << dp[weight] << endl;

}

}

//有先决条件的购买,即手里有多少钱 才跟你交易类型

#include<bits/stdc++.h>

using namespace std;

const int MAX = 0x3f3f3f3f;

const int MIN = 0xc0c0c0c0;

const int maxn = 1e2 * 5 + 5;

int dp[maxn * 10];

struct node

{

int p, q, v;

}a[maxn];

int comp(node x, node y)

{

return x.q - x.p < y.q - y.p;

}

int main()

{

int n, m;

while (~scanf("%d%d", &n, &m))

{

int i, j;

for (i = 1; i <= n; i++)

scanf("%d%d%d", &a[i].p, &a[i].q, &a[i].v);

sort(a + 1, a + n + 1, comp);

memset(dp, 0, sizeof(dp));

for (i = 1; i <= n; i++)                      

{

for (j = m; j >= a[i].q; j--)

{

dp[j] = max(dp[j], dp[j - a[i].p] + a[i].v);

printf("%d %d %d\n", i, j, dp[j]);

}

}

cout << dp[m] << endl;

}

}

//二维费用完全背包#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e2 + 5;

const int INF = 0x3f3f3f3f;

int w[maxn], v[maxn], dp[maxn][maxn];

int main()

{

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

Page 255: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

int ex, weight, n, tot;

while (~scanf("%d%d%d%d", &ex, &weight, &n, &tot))

{

int i, j, k;

for (i = 1; i <= n; i++)

scanf("%d%d", &v[i], &w[i]);    

memset(dp, 0, sizeof(dp));

int ans = INF;

for (i = 1; i <= n; i++)

{

for (j = w[i]; j <= weight; j++)

{

for (k = 1; k <= tot; k++)

{

dp[j][k] = max(dp[j][k], dp[j - w[i]][k - 1] + v[i]);

if (dp[j][k] >= ex && j < ans)

ans = j;

}

}

}

if (ans != INF)

cout << weight - ans << endl;

else

cout << -1 << endl;

}

}

//分组背包 每组至少选一个

const int maxn = (int)1e4 + 10;

int n, m, k;

vector <pii> Group[11];

void Input()

{

int a, b, c;

for (int i = 1; i <= k; i++) Group[i].clear();

for (int i = 1; i <= n; i++)

{

scanf("%d%d%d", &a, &b, &c);

Group[a].pb(pii(b, c));

}

}

int dp[12][maxn];

void Solve()

{

int sum = 0, value = 0;

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

Page 256: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

for (int i = 1; i <= k; i++)

{

if (Group[i].empty())

{

puts("Impossible");

return;

}

sort(all(Group[i]));

sum += Group[i][0].fi, value += Group[i][0].se;

}

if (sum > m)

{

puts("Impossible");

return;

}

if (sum == m)

{

printf("%d\n", value);

return;

}

CLR(dp, 0);

for (int i = 1; i <= k; i++)

for (auto it : Group[i])

for (int j = m; j >= it.fi; j--)

dp[i][j] = max(dp[i][j], max(dp[i][j - it.fi] + it.se, dp[i - 1][j

- it.fi] + it.se));

printf("%d\n", dp[k][m]);

}

int main()

{

while (scanf("%d%d%d", &n, &m, &k) != EOF)

{

Input(); Solve();

}

}

//分组背包 记录路径

#include <bits/stdc++.h>

using namespace std;

inline int read()

{

char c = getchar(); int ans = 0, vis = 1;

while (c < '0' || c > '9') { if (c == '-') vis = -vis;  c = getchar(); }

while (c >= '0' && c <= '9') { ans = ans * 10 + c - '0'; c = getchar(); }

return ans * vis;

}

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

Page 257: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

const int maxn = (int)1e4 + 10;

int n, c[5];

int a[] = {0, 1, 5, 10, 25 };

int dp[maxn];

int path[maxn];

int used[maxn];

void Solve()

{

CLR(dp, -1); dp[0] = 0; CLR(path, -1);

for (int i = 1; i <= 4; i++)

{

if (c[i] == 0) continue;

for (int j = 0; j <= n; j++) used[j] = 0;

for (int j = a[i]; j <= n; j++)

{

if (dp[j - a[i]] + 1 > dp[j] && dp[j - a[i]] != -1 && used[j - a[i]] +

1 <= c[i])

{

dp[j] = dp[j - a[i]] + 1;

used[j] = used[j - a[i]] + 1;

path[j] = i;

}

}

}

if (dp[n] == -1)

puts("Charlie cannot buy coffee.");

else

{

CLR(c, 0);

int it = path[n];

while (it != -1)

{

c[it]++;

n -= a[it];

it = path[n];

}

printf("Throw in %d cents, %d nickels, %d dimes, and %d quarters.\n",

c[1], c[2], c[3], c[4]);

}

}

bool check()

{

for (int i = 1; i <= 4; i++)

if (c[i]) return false;

return true;

}

int main()

{

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

Page 258: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

while (scanf("%d", &n))

{

for (int i = 1; i <= 4; i++) c[i] = read();

if (n == 0 && check()) return 0;

Solve();

}

}

//两个小孩分糖,分到的数量要相近,如果总数量为偶数 则两个都为 n / 2 如果是奇数 那么是 n / 2 + 1

和 n / 2 然后 重量要尽量相同//考虑 F[i] |= F[i - arr[j]] << 1; 表示 i 这个数能用j拼出来

const int maxn = (int)1e5 + 10;

int t, n, sum, kase = 1;

int arr[200];

inline bool Input()

{

if (t == 0) return false; t--;

__read(n); sum = 0;

F(i, 1, n) __read(arr[i]), sum += arr[i];

return true;

}

ll dp[maxn];

inline void Solve()

{

dp[0] = 1;

F(i, 1, sum >> 1) dp[i] = 0;

F(i, 1, n)

{

for (int j = sum >> 1; j >= arr[i]; j--)

{

dp[j] |= (dp[j - arr[i]] << 1);

//printf("%d %d\n", j, dp[j]);

}

}

int mid = (n + 1) >> 1;

for (int i = (sum >> 1); i >= 1; i--)

{

if ((dp[i] & (1ll << mid)) != 0)

{

printf("Case %d: %d %d\n", kase++, i, sum - i);

return;

}

}

}

inline void Run()

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466

467

468

469

470

471

472

473

474

475

476

477

478

479

480

481

482

483

484

485

486

487

488

489

490

491

492

493

Page 259: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

{

#ifdef LOCAL

freopen("Test.in", "r", stdin);

//freopen("1.out", "w+", stdout);

#endif

__read(t);

while (Input())

Solve();

#ifdef LOCAL

fclose(stdin);

//fclose(stdout);

#endif

}

int main()

{

Run();

return 0;

}

//恰好拼成k件 求拼成的体积不同的数量// 先减去a[1]   然后用其他数 拼出来,维护最小可以用几次拼出来, 假如可以拼出 V 那么 v + a[1]

* k 一定可以拼出来// 然后次数都是k 只要 最小值是<= k 因为如果不够k次 直接+ 0 就可以 因为此时 arr[0] = 0;

#include <bits/stdc++.h>

int n, k, pos;

int arr[maxn];

inline bool Input()

{

if (__read(n), __read(k), n == EOF) return false;

F(i, 1, n) __read(arr[i]); sort(arr + 1, arr + 1 + n);  pos = arr[n] * k; F(i,

2, n) arr[i] -= arr[1];

return true;  

}

int dp[Maxn];

inline void Solve()

{

CLR(dp, 0x3f); dp[0] = 0;

F(i, 2, n)

{

//if (i != 1 && arr[i] == arr[i - 1]) continue;

int limit = arr[i] * k;

F(j, arr[i], pos)

dp[j] = min(dp[j], dp[j - arr[i]] + 1);

}

int ans = 1;

494

495

496

497

498

499

500

501

502

503

504

505

506

507

508

509

510

511

512

513

514

515

516

517

518

519

520

521

522

523

524

525

526

527

528

529

530

531

532

533

534

535

536

537

538

539

540

541

542

543

544

Page 260: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

F(i, 1, pos) if (dp[i] <= k) ans++;  

write(ans), p10;

}

//多重背包

#include <bits/stdc++.h>

using namespace std;

#define READ freopen("Test.in", "r", stdin);

#define N 1010

#define M 100010

#define ll long long

#define INFLL 0x3f3f3f3f3f3f3f3f

#define INF 0x3f3f3f3f

int n, m;

int A[N], C[N];

int dp[M];

inline void work()

{

dp[0] = 0;

for (int i = 1; i <= m; ++i) dp[i] = -INF;

for (int i = 1; i <= n; ++i)

{

if (A[i] * C[i] >= m)

{

for (int j = A[i]; j <= m; ++j)

dp[j] = max(dp[j], dp[j - A[i]] + A[i]);

}

else

{

int tmp = C[i];

for (int k = 1; k < tmp; tmp -= k, k <<= 1)

{

for (int j = m; j >= k * A[i]; --j)

dp[j] = max(dp[j], dp[j - k * A[i]] + k * A[i]);

}

for (int j = m; j >= tmp * A[i]; --j)

dp[j] = max(dp[j], dp[j - tmp * A[i]] + tmp * A[i]);

}

}

}

int main()

{

#ifdef LOCAL

READ;

545

546

547

548

549

550

551

552

553

554

555

556

557

558

559

560

561

562

563

564

565

566

567

568

569

570

571

572

573

574

575

576

577

578

579

580

581

582

583

584

585

586

587

588

589

590

591

592

593

594

595

596

597

Page 261: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

树的前序中序转后序

#endif

while (scanf("%d%d", &n, &m) && n && m)

{

for (int i = 1; i <= n; ++i)

scanf("%d", A + i);

for (int i = 1; i <= n; ++i)

scanf("%d", C + i);

work();

int cnt = 0;

for (int i = 1; i <= m; ++i) if (dp[i] > 0)

cnt++;

printf("%d\n", cnt);

}

return 0;

}

598

599

600

601

602

603

604

605

606

607

608

609

610

611

612

vector <int> pre, in, ans;

void post(int root, int start, int end)

{

if (start >= end)

return;

int i = start;

while (i < end && in[i] != pre[root])

i++;

int len = i - start;

post(root + 1, start, i);

post(root + len + 1, i + 1, end);

ans.pb(pre[root]);

}

void print(vector <int> v)

{

vector <int>::iterator it;

for (it = v.begin(); it != v.end(); it++)

{

if (it != v.begin())

printf(" ");

printf("%d", (*it));

}

printf("\n");

}

int main()

{

stack <int> st;

int n;

scanf("%d", &n);

int m = n << 1;

string s;

int num;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

Page 262: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

过桥问题&倒水问题

for (int i = 0; i < m; i++)

{

cin >> s;

if (s == "Push")

{

scanf("%d", &num);

st.push(num);

pre.pb(num);

}

else

{

in.pb(st.top());

st.pop();

}

}

post(0, 0, n);

print(ans);

}

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

#include<bits/stdc++.h>

using namespace std;

const int MAXN = 1000;  

int cmp(const void *x,const void *y)  

{  

   return *(int *)x-*(int *)y;  

}  

int main()  

{  

   cout<<"热门智力题 - 过桥问题"<<endl;  

   cout<<" --by MoreWindows( http://blog.csdn.net/MoreWindows )--\n"<<endl;    

 

   int n, i, sum, a[MAXN];  

   cout<<"请输入人数:";  

   cin>>n;  

   cout<<"请输入每个人过桥时间,以空格分开"<<endl;  

   for (i = 0; i < n; i++)  

       cin>>a[i];  

   qsort(a, n, sizeof(a[0]), cmp);  

   sum = 0;  

   for (i = n - 1; i > 2; i = i - 2)  

  {    

       //最小者将最大2个送走或最小2个将最大2个送走  

       if (a[0] + a[1] + a[1] + a[i] < a[0] + a[0] + a[i - 1] + a[i])  

           sum = sum + a[0] + a[1] + a[1] + a[i];  

       else  

           sum = sum + a[0] + a[0] + a[i - 1] + a[i];    

  }  

   if (i == 2)  

       sum = sum + a[0] + a[1] + a[2];  

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

Page 263: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

   else if (i == 1)  

       sum = sum + a[1];  

   else  

       sum = a[0];  

   cout<<"最短过桥时间为:"<<sum<<endl;  

   return 0;  

}  

//热门智力题 - 打水问题  

//基本思想:用小桶容量的倍数对大桶的容量进行取余。  

//指导方针:不断用小桶装水倒入大桶,大桶满了立即清空,  

//每次判断下二个桶中水的容量是否等于指定容量。  

#include  

#include  

#include  

using namespace std;  

const string OPERATOR_NAME[7] = {  

   "装满A桶","装满B桶",  

   "将A桶清空","将B桶清空",  

   "A桶中水倒入B桶","B桶中水倒入A桶",  

   "成功"  

};  

int main()  

{  

 

   int    a_volume, b_volume, goal_volume;  

   vector record;       //记录操作步数  

   int    ai;  

   int    i, a_water, b_water;  

 

   cout<<"请输入A桶容量,B桶容量,目标容量:";  

   cin>>a_volume>>b_volume>>goal_volume;  

   a_water = b_water = 0; //A桶,B桶中有多少升水  

   char szTemp[30];  

   while (true)  

  {  

       if (a_water == 0)//A桶没水,就装满水  

      {  

           a_water = a_volume;  

           sprintf(szTemp, "         A:%d B:%d", a_water, b_water);  

           record.push_back(OPERATOR_NAME[0] + szTemp);//fill A  

      }  

       else  

      {  

           //如果A桶的水比(B桶容量-B桶的水)要多  

           if (a_water > b_volume - b_water)  

          {  

               //A桶的水==A桶的水+B桶的水-B桶容量  

               a_water = a_water + b_water- b_volume;  

               b_water = b_volume;      //B桶的水装满了  

               sprintf(szTemp, " A:%d B:%d", a_water, b_water);  

               record.push_back(OPERATOR_NAME[4] + szTemp);//A->B    

               if (a_water == goal_volume)  

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

Page 264: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

多项式

                   break;  

               b_water = 0;            //将B桶清空  

               sprintf(szTemp, "       A:%d B:%d", a_water, b_water);  

               record.push_back(OPERATOR_NAME[3] + szTemp);  

          }  

           else  

          {  

               //B桶的水==A桶的水+B桶的水  

               b_water += a_water;  

               a_water = 0;  

               sprintf(szTemp, " A:%d B:%d", a_water, b_water);  

               record.push_back(OPERATOR_NAME[4] + szTemp);//A->B  

               if (b_water == goal_volume)  

                   break;  

          }  

      }  

  }  

   record.push_back(OPERATOR_NAME[6]); //success  

   cout<<"\n---------------------------------------------------"<<endl;  

   cout<<"一个可行的倒水方案如下"<<endl;  

   vector::iterator pos;  

   for (pos = record.begin(); pos != record.end(); pos++)  

       cout<<*pos<<endl;  

   cout<<"---------------------------------------------------"<<endl;  

   return 0;  

}  

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int MOD = 1e9 + 7;

struct Polynomial

{

int len;

ll x[500];

Polynomial () { len = 0; for (int i = 0; i < 500; i++) x[i] = 0;}

Polynomial operator +(const Polynomial& r)

{

Polynomial res = *this;

res.len = max(res.len, r.len);

for (int i = 0; i < r.len; i++) res.x[i] += r.x[i];

while (res.len > 0 && res.x[res.len - 1] == 0) res.x[res.len - 1] = 0, --

res.len;

return res;

}

Polynomial operator*(const Polynomial& r)

{

Polynomial res = Polynomial();

res.len = r.len + len - 1;

for (int i = 0; i < r.len; i++)

{

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

Page 265: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

中缀表达式求值

for (int j = 0; j < len; j++)

{

res.x[i + j] = (res.x[i + j] + x[j] * r.x[i]) % MOD;

}

}

while (res.len > 0 && res.x[res.len - 1] == 0) res.x[res.len - 1] = 0, --

res.len;

return res;

}

};

24

25

26

27

28

29

30

31

32

33

//中缀表达式求值/*

中缀表达式难以直接求值,要通过转化为其后缀表达式计算。转化和求值过程都需要借助STL的STACK来实现。

转化:

1)顺序扫描中缀表达式,

当遇到一个左括号时立即将其压栈;当遇到对应的右括号时,将栈中的操作符弹出并输出,直到遇到左括号。最后再弹出左括号(但不输出);当遇到一个分量时,立即输出;当遇到一个操作符时,将它与栈顶操作符比较:<1>如果它比栈顶的操作符优先级高,或者它是左括号后的第一个操作符,则将其压入栈;<2>否则(低或相等),将栈顶操作符弹出并输出;

<3>继续比较,如果它比新的栈顶操作符的优先级高,跳到 2),否则,重复<2> <3>。

2)如果扫描到了中缀表达式的末尾,将栈中的剩余的操作符全部弹出并输出,否则重复 1)。

求值:

中缀表达式的求值需要其后缀表达式(可用char 型的数组保存)和一个运算分量栈,借用后缀表达式求值也体现了其价值。

1)顺序扫描后缀表达式,

当遇到运算分量时将其压入运算分量栈;

当遇到运算符时,弹出两个运算分量进行计算,并将结果压栈。

2)当扫描到后缀表达式末尾再次计算结果时,栈顶元素就是所求表达式的值,否则,重复 1)。*/

#include <iostream>

#include <stack>

using namespace std;

char suf_exp[100];//储存后缀表达式int z=0;//suf_exp的下标变量

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

Page 266: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

bool cmp(char a,char b){//若操作符a和b的优先级    if(a=='*'||a=='/'){//a的高        if(b=='*'||b=='/')  return false;

       else

           return true;

  }

   else//b的高        return false;

}

void get_suf_exp(string s){

   cout<<"It's suffix expression: ";

   stack<char> ope_stack;//操作符栈    int len=s.length();

   for(int i=0;i<len;i++){//1)

       char t=s[i];

       if(t=='(')   ope_stack.push(s[i]);

       else if(t==')'){

           char ope=ope_stack.top();

           while(ope!='('){

               suf_exp[z++]=ope;

               cout<<ope<<" ";

               ope_stack.pop();

               ope=ope_stack.top();

          }

           ope_stack.pop();//pop '('

      }

       else if(t>='0'&&t<='9'){

           suf_exp[z++]=t;

           cout<<t<<" ";

      }

       else{

           if(ope_stack.empty())    ope_stack.push(t);

           else{

               char stp=ope_stack.top();

               if(stp=='('||cmp(t,stp))  ope_stack.push(t);// 1)<1>

               else{                                       // 1)<2> <3>

                   while(!cmp(t,stp)&&!ope_stack.empty()&&stp!='('){

                       ope_stack.pop();

                       cout<<stp<<" ";

                       suf_exp[z++]=stp;

                       if(!ope_stack.empty())

                           stp=ope_stack.top();

                  }

                   ope_stack.push(t);

              }

          }

      }

  }

   while(!ope_stack.empty()){//2)

       char t=ope_stack.top();

       cout<<t<<" ";

       suf_exp[z++]=t;

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

Page 267: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

       ope_stack.pop();

  }

}

void calculate(string s){

   stack<float> val_stack;

   val_stack.push(1.0*(suf_exp[0]-'0'));//将字符转化为浮点型数    for(int i=1;i<z;i++){

       char t=suf_exp[i];

       if(t>='0'&&t<='9')    val_stack.push((t-'0')*1.0);

       else{

           float x=val_stack.top(); val_stack.pop();

           float y=val_stack.top(); val_stack.pop();

           float tmp;

           if(t=='+')  tmp=x+y;

           else if(t=='-') tmp=y-x;

           else if(t=='*') tmp=x*y;

           else    tmp=y/x;

           val_stack.push(tmp);

//           cout<<endl<<tmp;

      }

  }

   cout<<endl<<s<<" = "<<val_stack.top()<<endl;

}

int main(){

   string in_exp;//输入中缀表达式    cin>>in_exp;

   get_suf_exp(in_exp);

   calculate(in_exp);

   return 0;

}

/*

它们都是对表达式的记法,因此也被称为前缀记法、中缀记法和后缀记法。它们之间的区别在于运算符相对与操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前;中缀和后缀同理。

举例:(3 + 4) × 5 - 6 就是中缀表达式- × + 3 4 5 6 前缀表达式3 4 + 5 × 6 - 后缀表达式

中缀表达式(中缀记法)中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间。中缀表达式是人们常用的算术表示方法。虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值。对计算机来说,计算前缀或后缀表达式的值非常简单。

前缀表达式(前缀记法、波兰式)前缀表达式的运算符位于操作数之前。

前缀表达式的计算机求值:

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

Page 268: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 op 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。例如前缀表达式“- × + 3 4 5 6”:(1) 从右至左扫描,将6、5、4、3压入堆栈;(2) 遇到+运算符,因此弹出3和4(3为栈顶元素,4为次顶元素,注意与后缀表达式做比较),计算出3+4的值,得7,再将7入栈;(3) 接下来是×运算符,因此弹出7和5,计算出7×5=35,将35入栈;(4) 最后是-运算符,计算出35-6的值,即29,由此得出最终结果。可以看出,用计算机计算前缀表达式的值是很容易的。

将中缀表达式转换为前缀表达式:遵循以下步骤:(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;(2) 从右至左扫描中缀表达式;(3) 遇到操作数时,将其压入S2;(4) 遇到运算符时,比较其与S1栈顶运算符的优先级:(4-1) 如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符入栈;(4-2) 否则,若优先级比栈顶运算符的较高或相等,也将运算符压入S1;(4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;(5) 遇到括号时:(5-1) 如果是右括号“)”,则直接压入S1;(5-2) 如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号丢弃;(6) 重复步骤(2)至(5),直到表达式的最左边;(7) 将S1中剩余的运算符依次弹出并压入S2;(8) 依次弹出S2中的元素并输出,结果即为中缀表达式对应的前缀表达式。*/

/*

后缀表达式(后缀记法、逆波兰式)后缀表达式与前缀表达式类似,只是运算符位于操作数之后。

后缀表达式的计算机求值:与前缀表达式类似,只是顺序是从左至右:从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素 op 栈顶元素),并将结果入栈;重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。例如后缀表达式“3 4 + 5 × 6 -”:(1) 从左至右扫描,将3和4压入堆栈;(2) 遇到+运算符,因此弹出4和3(4为栈顶元素,3为次顶元素,注意与前缀表达式做比较),计算出3+4的值,得7,再将7入栈;(3) 将5入栈;(4) 接下来是×运算符,因此弹出5和7,计算出7×5=35,将35入栈;(5) 将6入栈;(6) 最后是-运算符,计算出35-6的值,即29,由此得出最终结果。

将中缀表达式转换为后缀表达式:与转换为前缀表达式相似,遵循以下步骤:(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;(2) 从左至右扫描中缀表达式;(3) 遇到操作数时,将其压入S2;(4) 遇到运算符时,比较其与S1栈顶运算符的优先级:

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

Page 269: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

对拍程序

(4-1) 如果S1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;(4-2) 否则,若优先级比栈顶运算符的高,也将运算符压入S1(注意转换为前缀表达式时是优先级较高或相同,而这里则不包括相同的情况);(4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;(5) 遇到括号时:(5-1) 如果是左括号“(”,则直接压入S1;(5-2) 如果是右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到左括号为止,此时将这一对括号丢弃;(6) 重复步骤(2)至(5),直到表达式的最右边;(7) 将S1中剩余的运算符依次弹出并压入S2;(8) 依次弹出S2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式(转换为前缀表达式时不用逆序)。*/

187

188

189

190

191

192

193

194

195

196

#include<bits/stdc++.h>

using namespace std;

#define random(a,b) ((a)+rand()%((b)-(a)+1))

typedef pair <int, int> pii;

#define ll long long

stringstream ss;

int main( int argc, char *argv[] )

{

int seed=time(NULL);

if(argc)

{

ss.clear();

ss<<argv[1];

ss>>seed;

}

srand(seed);

//以上为随机数初始化,请勿修改 //random(a,b)生成[a,b]的随机整数

//以下写你自己的数据生成代码 n

/*

Dup4 update in Aug 13 2018

*/

#include <bits/stdc++.h>

using namespace std;

string s;

int main()

{

   for (int T = 1; T <= 10000000000; ++T)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

Page 270: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

TSP旅行商问题

  {

       system("rand.exe > data.in");

       

       double st_my = clock();

       system("my.exe < data.in > my.out");

       double ed_my = clock();

       

       double st_std = clock();

       system("std.exe < data.in > std.out");

       double ed_std = clock();

       

       printf("Test Point%d: ", T);

       if (system("fc my.out std.out > result.out"))

      {

           puts("Wrong Answer");

           printf("View the Data?(if yes, input \"ok\")\n");

           cin >> s;

           if (s == "ok")

          {

               puts("Data:"); system("type data.in"); puts("");

               puts("My:");   system("type my.out");  puts("");

               puts("Std:");  system("type std.out"); puts("");  

}

           printf("View the compare result?(if yes, input \"ok\")\n");

           cin >> s;

           if (s == "ok")

          {

               puts("Compare result"); system("type result.out"); puts("");

          }

           system("pause");

      }

       else

      {

           puts("Accepted");

           printf("Time_std: %.0lfms\n", ed_std - st_std);

           printf("Time_my: %.0lfms\n", ed_my - st_my);

      }

       puts("");

  }

}

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

/*

TSP问题(旅行商问题)是指旅行家要旅行n个城市,要求各个城市经历且仅经历一次然后回到出发城市,并要求所走的路程最短。

*/

int len = 1 << m;

for (int i = 1; i < len; i++) // 不需要 0 这个状态 因为刚开始的起点肯定是一个传送门 {

for (int j = 0; j < m; j++)

{

int cur = (1 << j);

1

2

3

4

5

6

7

8

9

Page 271: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

二分高精度开方以及多次方

if ((cur & i) == 0) continue;

if (i == cur) continue;

else

dp[i][j] = INF;

for (int k = 0; k < m; k++)

{

int cnt = (1 << k);

if (((1 << k) & i) == 0 || k == j) continue;

ll cost = dp[i^cur][k] + (ll)G[k][j];    

// i^cur 表示 从不包含j点的状态转移过来 dp[i^cur][k] 就是 在状态i^cur 的时候 最后那个结点是k的花费 这样就是正确的 其实就是 TSP 问题

dp[i][j] = min(dp[i][j], cost);

}

}

}

10

11

12

13

14

15

16

17

18

19

20

21

22

23

//二分开方    public static BigInteger check(BigInteger n,BigInteger x) {

       BigInteger ans=BigInteger.valueOf(1);

       BigInteger a=BigInteger.valueOf(1);

       for(BigInteger i=BigInteger.ZERO;i.compareTo(n)<0;i=i.add(a)) {

           ans=ans.multiply(x);

      }

       return ans;

  }

   static BigInteger Get(BigInteger m) {

       BigInteger l=BigInteger.ZERO;

       BigInteger a=BigInteger.valueOf(2);

       BigInteger b=BigInteger.valueOf(1);

       BigInteger r=BigInteger.valueOf(1);

       BigInteger mid=BigInteger.ZERO;

       while(check(BigInteger.valueOf(2),r).compareTo(m)<=0) {

           l=r;

           r=r.multiply(a);

      }

       while(l.compareTo(r)<=0) {

           mid=l.add(r).divide(a);

           if(check(BigInteger.valueOf(2),mid).compareTo(m)<=0) l=mid.add(b);

           else r=mid.subtract(b);

      }

       return r;   //返回的是开方后的值   }

   

//二分开n^(1/m) 只求整数部分  

import java.io.BufferedInputStream;

import java.math.BigInteger;

import java.util.Scanner;

public class Main {

   public static void  main(String args[]){

       Scanner cin = new Scanner(new BufferedInputStream(System.in));

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

Page 272: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

Vim相关设置

       BigInteger n;

       int m;

       while(cin.hasNext()) {

         m = cin.nextInt();

         n = cin.nextBigInteger();

         BigInteger l = BigInteger.ZERO;

         BigInteger r = BigInteger.ONE;

         while(r.pow(m).compareTo(n) != 1) {      // r^m <= n

             l = r;

             r = r.multiply(BigInteger.valueOf(2));

        }

         while(l.add(BigInteger.valueOf(1)).compareTo(r) == -1) {   // l + 1 <= r

             BigInteger mid = (l.add(r)).divide(BigInteger.valueOf(2));

             if(mid.pow(m).compareTo(n) != 1) {   // mid ^ m <= n

                 l = mid;

            } else {

                 r = mid;

            }

        }

         BigInteger ans;

         if(r.pow(m).compareTo(n) != 1) {

             ans = r;

        } else {

             ans = l;

        }

         System.out.println(ans);

      }

  }

}

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

apt-get remove --purge xxx # 移除应用及配置apt-get autoremove # 移除没用的包ctrl+alt+t 打开命令行

vim

u 撤销操作Ctrl + r 恢复刚才撤销的操作

列操作Ctrl + v 进入可视“块”操作Shift + (i) 输入要插入的内容ESC按两次,会在每行的选定的区域出现插入的内容

复制粘贴

"号粘贴板 临时粘贴板+号粘贴板  系统粘贴板

全局复制 "+y

全局粘贴 "+p

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

Page 273: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack

 

 

 

 

 

 

 

 

 

 

 

 

yy复制游标所在行整行 或大写一个Y

2yy或y2y复制两行。y^复制至行首,或y0。不含游标所在处字元y$复制至行尾。含游标所在处字元yw复制一个word

y2w复制两个字(单词)yG复制至档尾y1G复制至档首p小写p代表贴至游标后(下)P大写P代表贴至游标前(上)

gg 跳到首行v visual模式G 跳到末行

复制也有ggyG一说。

复制到外部程序用ggVG”+y

$vim --version

或者是

$vim --version | grep clipboard

查看xterm_clipboard前是+还是-,+表示可用,-表示不可用。

如果xterm_clipboard不可用,需要安装vim的插件

$sudo apt-get install vim vim-scripts vim-gtk vim-gnome

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

Page 274: HZNU TI1050 Programing list - files-cdn.cnblogs.com · HZNU_TI1050 Programing list Build by Dup4 at September 11, 2018 contents STL: 1. STL-set 2. STL-vector 3. STL-string 4. STL-stack