###### tags: `UVa`
- [ ] uncheck
# UVa d712. The 3n + 1 problem
### 1st Ideas of solving a problem
> 1. Input data( a and b) in main function, and use another function 'test' in order to check the answer of each input data in this 3n+1 algo.
> 2. In 'test' function, use a for loop and while to check each cycle length in the scope of a and b.
> 3. In 'test' function, use a array to save each cycle length.
> 4. In 'test' function, use if and else to find out the biggest integer in array.
> Bug: TLE. If input datas are too large (maybe 1000000 and one integer is 4 byte= 4MB).
> Please compare to c039.
```=c
#include<stdio.h>
#define MAX_LEN 10000000
void threen(int,int);
void segment_tree(int*,int*,int,int,int);
void Find_max(int*,int,int,int);
int tree[MAX_LEN]={0};//建立待會要用的線段樹陣列存在tree陣列中並且初始化
int main(){
int input1,input2;
scanf("%d%d",&input1,&input2);
printf("%d %d",input1,input2);
if(input1>input2){
int temp=input1;
input1=input2;
input2=temp;
}
threen(input1,input2);//把起始值和終點值傳入做計算
printf(" ");
printf("%d\n",tree[0]);
return 0;
}
void threen(int input1,int input2){//先求出題目給區間的3n+1值然後再用線段樹去求出最大值 時間才會是O(logn)
int size=(input2-input1+1);//先計算要宣告的陣列大小,arr存3n+1結果
int arr[size];
for(int i=input1,j=0;i<=input2,j<size;i++,j++){
int ans=1;
int temp=i;
while(temp!=1){
if(temp%2==1){
temp=3*temp+1;
ans++;
}
else if(temp%2==0){
temp=temp/2;
ans++;
}
}
arr[j]=ans;//將最大值length存入arr[]陣列中
}
int father_INDEX=0;//root編號從0開始
int arr_start=0;//原本陣列arr的起始index
int arr_end=size-1;//原本陣列arr的終止index
void segment_tree(int*arr,int*tree,int father_INDEX ,int arr_start,int arr_end);//(原資料的陣列指標,新建立的樹陣列指標,樹的根節點,原本數組陣列的起始,原本數組陣列的終點)
}
void segment_tree(int*arr,int*tree,int father_INDEX ,int arr_start,int arr_end){
if(arr_start==arr_end){//如果資料只有一個
tree[father_INDEX]=arr[arr_start];//把資料丟入父點
}
else{//資料不只一個 使用divide and conquer中的divide往下切割
int mid=(arr_start+arr_end)/2;//求出資料中間index
int left_INDEX=2*father_INDEX+1;//求出左子點的index
int right_INDEX=2*father_INDEX+2;//求出右子點的index
segment_tree(arr,tree,left_INDEX ,arr_start,mid);//遞回往下作父點變成左子點
segment_tree(arr,tree,right_INDEX ,mid+1,arr_end);//遞回往下作父點變成右子點
Find_max(tree,father_INDEX,left_INDEX,right_INDEX );//直到做到leave的編號後 去做比較找最大值,並將最大值往上存回父點
}
}
void Find_max(int*tree,int father_INDEX,int left_INDEX,int right_INDEX){
if(tree[left_INDEX]>=tree[right_INDEX]){
tree[father_INDEX]=tree[left_INDEX];
}
else{
tree[father_INDEX]=tree[right_INDEX];
}
}
```