ZeroJudge d712 - The 3n + 1 problem

Link: http://zerojudge.tw/ShowProblem?problemid=d712

Zerojudge原創題庫,UVA 100的加強版 (其實差滿多的)
先DP算好n=1~1000000時的cycle length,建立線段樹,之後就直接查詢RMQ就行了,然後有個i>j的陷阱(竟然掉進去了真不應該)

AC code
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
#include<bits/stdc++.h>
#define MAX 1000000
using namespace std;
int dp[MAX+1];
int seg[4000010];
int solve(long long n)
{
if(n<=MAX && dp[n]!=-1) return dp[n];
int a;
if(n%2==0) a=solve(n/2)+1;
else a=solve(3*n+1)+1;
if(n<=MAX) dp[n]=a;
return a;
}
void build(int l,int r,int idx)
{
if(l==r) seg[idx]=dp[l];
else
{
int mid=(l+r)/2;
build(l,mid,idx*2);
build(mid+1,r,idx*2+1);
seg[idx]=max(seg[idx*2],seg[idx*2+1]);
}
}
int query(int l,int r,int L,int R,int idx)
{
if(l==L&&r==R) return seg[idx];
int mid=(L+R)/2;
if(r<=mid) return query(l,r,L,mid,idx*2);
else if(l>mid) return query(l,r,mid+1,R,idx*2+1);
else return max( query(l,mid,L,mid,idx*2), query(mid+1,r,mid+1,R,idx*2+1) );
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);

memset(dp,-1,sizeof dp);
dp[1]=1;
for(int i=1;i<=MAX;i++)
solve(i);
build(1,MAX,1);

int i,j,l,r;
while(cin>>i>>j)
{
if(i>j) tie(l,r)=make_tuple(j,i);
else tie(l,r)=make_tuple(i,j);
cout<<i<<' '<<j<<' '<<query(l,r,1,MAX,1)<<endl;
}
}