vis

[noi31]MST

社会主义新天地 提交于 2019-11-26 09:51:44
定义 dp[i] 表示当前连通块状态为 i 的方案数(状态记录该状态每一个连通块的大小),那么从小到大枚举每条边,考虑这条边在不在最小生成树上: 1. 如果不在最小生成树上,那么这条边有$\sum_{i=1}^{scc}\sum_{j=i+1}^{scc}Si\cdot Sj$ ( Si 表示第 i 个连通块的点数)种位置,即每一个状态的方案都乘上这个数; 2. 如果在最小生成树上,那么他一定会把某两个连通块连起来,枚举这两个连通块并递推到新的状态。 那么这样的时间复杂度是多少呢?大约是$o(Pn\cdot n^{3})$ ( Pn 表示将 n 划分成一些数的和的方案数,$P_{40}\approx 40000$ ,$n^{2}$ 是枚举连通块,另一个 n 是 hash 的时间),显然这样是会炸掉的…… 似乎这个状态的记录方式可以改变,可改为每一个大小的连通块出现次数,由于最多只有 $\sqrt{n}$ 种方案,枚举两个连通块也仅有 n 的时间复杂度,总时间复杂度降为 $o(Pn\cdot n^{2})$ 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define mod 1000000007 4 map<int,int>vis; 5 int n,m,k,di[40001][41],a[41],mi[41],b[1001]

【二叉树】二叉树学习小结1

你离开我真会死。 提交于 2019-11-26 06:05:05
一、主干功能部分代码分享 1.存储定义 struct Tree{ char data;/*数据域*/ struct Tree *left;/*指针域-指向左子树*/ struct Tree *right;/*指针域-指向右子树*/ }; 2.按先序遍历输入的字符序列建立二叉树,如abc,de,g,f, (其中,表示空结点) #include <stdio.h> #include <string.h> #include <stdlib.h> struct Tree{ char data;/*数据域*/ struct Tree *left;/*指针域-指向左子树*/ struct Tree *right;/*指针域-指向右子树*/ }; int k; char st[104]; Tree * build_tree();/*建树*/ int main(){ while(~scanf("%s", st)){ k = 0; Tree *root; root = build_tree(); printf("%c\n", root->data); } return 0; } Tree * build_tree(){ Tree *rt; if(st[k] == ','){ rt = NULL; k++; } else { k++; rt = (struct Tree *)malloc(sizeof

E - Prime Path

荒凉一梦 提交于 2019-11-25 19:54:46
添加链接描述 The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change the four-digit room numbers on their offices. — It is a matter of security to change such things every now and then, to keep the enemy in the dark. — But look, I have chosen my number 1033 for good reasons. I am the Prime minister, you know! — I know, so therefore your new number 8179 is also a prime. You will just have to paste four new digits over the four old ones on your office door. — No, it’s not that simple. Suppose that I change the first digit to an