一种数组做法,一种指针做法
可以看出指针比数组所用时间少而且所占内存也少
不懂卢卡斯点这里传送门
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include<cstring>
using namespace std;
struct node{
int idx;
int size;
}a[1000000];
int ans;
void myinsert(int x){
int p=1;
while(a[p].size){
a[p].size++;
if(x>a[p].idx) p=2*p+1;
else p=2*p;
// cout<<"123"<<endl;
}
a[p].idx=x;
a[p].size=1;
}
typedef long long ll;
int quick_power_mod(int a,int b,int m){//pow(a,b)%m
int result = 1;
int base = a;
while(b>0){
if(b & 1==1){
result = (result*base) % m;
}
base = (base*base) %m;
b>>=1;
}
return result;
}
//计算组合数取模
ll comp(ll a, ll b, int p) {//composite num C(a,b)%p
if(a < b) return 0;
if(a == b) return 1;
if(b > a - b) b = a - b;
int ans = 1, ca = 1, cb = 1;
for(ll i = 0; i < b; ++i) {
ca = (ca * (a - i))%p;
cb = (cb * (b - i))%p;
}
ans = (ca*quick_power_mod(cb, p - 2, p)) % p;
return ans;
}
ll lucas(ll n, ll m, ll p) {
ll ans = 1;
while(n&&m&&ans) {
ans = (ans*comp(n%p, m%p, p)) % p;//also can be recusive
n /= p;
m /= p;
}
return ans;
}
int dfs(int t){
if(a[t].size==0)
return 1;
else return ((dfs(2*t+1)%9901*dfs(2*t))%9901*lucas(a[t].size-1,a[2*t].size,9901))%9901;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF&&n){
memset(a,0,sizeof(a));
for(int i=0;i<n;i++){
int x;
scanf("%d",&x);
if(i==0){
a[1].idx=x;
a[1].size=1;
}else myinsert(x);
}
// printf("%d\n",a[1].size);
ans=dfs(1);
printf("%d\n",ans);
}
return 0;
}
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include<cstring>
using namespace std;
struct node{
node* l;
node* r;
int idx;
int size;
node(){
idx=0;
size=0;
l=NULL;
r=NULL;
}
};
node* root;
void myinsert(int x){
node* t=root;
while(t->size){
t->size++;
if(x<=t->idx){
// printf("%d\n",t->idx);
if(t->l!=NULL) t=t->l;
else{
t->l=new node;
t=t->l;
}
}else{
// printf("%d\n",t->idx);
if(t->r!=NULL) t=t->r;
else{
t->r=new node;
t=t->r;
}
}
}
t->idx=x;
t->size=1;
}
typedef long long ll;
int quick_power_mod(int a,int b,int m){//pow(a,b)%m
int result = 1;
int base = a;
while(b>0){
if(b & 1==1){
result = (result*base) % m;
}
base = (base*base) %m;
b>>=1;
}
return result;
}
//计算组合数取模
ll comp(ll a, ll b, int p) {//composite num C(a,b)%p
if(a < b) return 0;
if(a == b) return 1;
if(b > a - b) b = a - b;
int ans = 1, ca = 1, cb = 1;
for(ll i = 0; i < b; ++i) {
ca = (ca * (a - i))%p;
cb = (cb * (b - i))%p;
}
ans = (ca*quick_power_mod(cb, p - 2, p)) % p;
return ans;
}
ll lucas(ll n, ll m, ll p) {
ll ans = 1;
while(n&&m&&ans) {
ans = (ans*comp(n%p, m%p, p)) % p;//also can be recusive
n /= p;
m /= p;
}
return ans;
}
int dfs(node* t){
// if(t!=NULL)
// printf("%d\n",t->idx);
if(t==NULL||t->size==0)
return 1;
return (dfs(t->l)*dfs(t->r)*lucas(t->size-1,t->l==NULL?0:t->l->size,9901))%9901;
}
void del(node* &t){
if(t==NULL) return;
del(t->l);
del(t->r);
delete t;
}
void print(node* t){
if(t==NULL) return ;
print(t->l);
print(t->r);
printf("%d ",t->idx);
}
int main()
{
int n;
// printf("%d\n",root->idx);
while(scanf("%d",&n)!=EOF&&n){
root=new node;
for(int i=0;i<n;i++){
int x;
scanf("%d",&x);
if(i==0){
root->idx=x;
root->size=1;
// root->l=NULL;
// root->r=NULL;
}else myinsert(x);
}
// printf("%d\n",root->l->l==NULL?1:0);
// print(root);
int ans=dfs(root);
printf("%d\n",ans);
del(root);
}
return 0;
}
/*
9
5 6 3 18 20 10 4 17 20
*/

本文探讨了使用数组和指针实现二叉树的方法,并对比了两种方式的时间和空间效率。通过具体的代码示例,展示了如何进行节点插入、递归遍历及计算组合数等操作。

被折叠的 条评论
为什么被折叠?



