摘要:
//很祼的并查集
#include "UnionFindSet.h"
#include <iostream>
using namespace std; int main()
{ UFS ufs; int P, X, Y; char ch; cin>>P; while(P--) { cin>>ch; if(ch == 'M') { cin>>X>>Y; ufs.Union(X,Y,-1); } else { cin>>X; ufs.Find(X); cout<<ufs.dept 阅读全文
摘要:
/* UnionFindSet.h 并查集,非递归方法,含路径压缩,数组从0开始
合并时,前者合并入后者,不区分大小
*/ #include <iostream> using namespace std; #define MAXN 30005 class UFS
{
public: int n; int father[MAXN+1];//集合根结点 int rank[MAXN+1]; //集合中点的个数 int depth[MAXN+1]; //每个结点改变一次所属的集合,增加一些值
public: UFS(int size = MAXN); vo... 阅读全文
摘要:
//很纯的二维树状数组
#include "TreeArray.h"
#include <iostream>
using namespace std; int main()
{ bool flag[MAX][MAX]; TreeArray ta(2); int m,x1,x2,y1,y2; char op; while(scanf("%d",&m)!=EOF) { memset(flag, 0, sizeof(flag)); ta.clear(); while(m--) { getchar(); scanf("%c" 阅读全文
摘要:
/*
TreeArray.h
树状数组,一维和二维都有。数组必须从1开始 问题:
已知数组a[],元素个数为n,现在更改a中的元素,要求得新的a数组中i到j区间内的和 解决方法:
从图中不难发现,c[k]存储的实际上是从k开始向前数k的二进制表示中右边第一个1所代表的数字
个元素的和(这么说可能有点拗口,令lowbit为k的二进制表示中右边第一个1所代表的数字,然后
c[k]里存的就是从a[k]开始向前数lowbit个元素之和)
C1 = A1
C2 = A1 + A2
C3 = A3
C4 = A1 + A2 + A3 + A4
C5 = A5
C6 = A5 + A6
C7 = A7
.. 阅读全文
摘要:
/*
取下前n个环步骤是先取下前n-2个环,再取下第n个环,再还原前n-2个环,最后取下前n-1个环。
递推公式:f(n) = f(n-1) + 2 * f(n-2) + 1
构造矩阵:
Fn(1,3) = |f(n) f(n-1) 1|
F2(1,3) = |f(2) f(1) 1| = |2 1 1| |1 1 0|
A(3,3) = |2 0 0| |1 0 1|
Fn = F2 * A^(n-2)
*/
#include "Mat.h"
#include <iostream>
using namespace std; int a[3][3] = {... 阅读全文
摘要:
/*
两个数论公式:
f(k) = ( (1+sqrt(5)) / 2 ) ^ k - ( (1-sqrt(5)) / 2) ^ k
(1+a)^n = Sum(C(k|n) * (a^k))
推导过程: Sum(C(k|n) * f(k))
= Sum(C(k|n) * ( (1+sqrt(5)) / 2 ) ^ k - ( (1-sqrt(5)) / 2) ^ k)
= Sum(C(k|n) * (1+sqrt(5)) / 2 ) ^ k) - Sum(C(k|n) * (1-sqrt(5)) / 2 ) ^ k)
= ( (3+sqrt(5)) / 2 ) ^ k - ( (3-sq.. 阅读全文