友链
瞎吹系列
题目大意:
题目链接:https://www.luogu.org/problemnew/show/P1001
给出
a
,
b
a,b
a,b两个数,输出
a
+
b
a+b
a+b。
思路:
caijiZYC
\texttt{caijiZYC}
caijiZYC 1秒后才开始学C++。
这道题大部分人的代码都是这样的
#include <cstdio>
using namespace std;
int a,b;
int main(){
scanf("%d%d",&a,&b);
printf("%d",a+b);
return 0;
}
无可否认,这种方法是在是太慢了。时间复杂度竟然高达
O
(
1
)
O(1)
O(1)!
于是
caijiZYC
\texttt{caijiZYC}
caijiZYC决定优化
A
+
B
P
r
o
b
l
e
m
A+B\ Problem
A+B Problem的代码!
我们把
A
A
A和
B
B
B化为二进制,我们发现,在进行
A
+
B
A+B
A+B时,如果
A
,
B
A,B
A,B在二进制下的某一位都为
0
0
0,那么把这两位加起来是十分浪费时间的!所以我们可以把这种情况直接
c
o
n
t
i
n
u
e
continue
continue掉,这样就可以优化时间!
这样的话,时间复杂度就被
caijiZYC
\texttt{caijiZYC}
caijiZYC降低到了
O
(
log
2
n
)
O(\log_2 n)
O(log2n)!
#include <cstdio>
#include <algorithm>
using namespace std;
const int LG=30;
int a,b,c,fa,fb;
int main()
{
scanf("%d%d",&a,&b);
fa=(a>=0?1:-1);
fb=(b>=0?1:-1);
a=abs(a); b=abs(b);
for (int i=0;i<=LG;i++)
{
if (!(a&(1<<i)) && !(b&(1<<i))) continue;
if (a&(1<<i)) c+=(1<<i)*fa;
if (b&(1<<i)) c+=(1<<i)*fb;
}
printf("%d\n",c);
return 0;
}
这样的话,程序就会大大加快,甚至在洛谷上跑
0
m
s
0ms
0ms!
设想一下,如果我们把
A
,
B
A,B
A,B转化为三进制,那么我们的时间复杂度就为
O
(
log
3
n
)
O(\log_3 n)
O(log3n),四进制的话就是
O
(
log
4
n
)
O(\log_4 n)
O(log4n)。这样下去,如果我们把
A
A
A和
B
B
B都化成
∞
\infty
∞进制的话,时间复杂度就是
O
(
log
∞
n
)
O(\log_{\infty} n)
O(log∞n)了!
只要我们设
∞
\infty
∞足够大,那么
O
(
log
∞
n
)
O(\log_{\infty} n)
O(log∞n)就会无限趋近于
O
(
0
)
O(0)
O(0),就使得
A
+
B
P
r
o
b
l
e
m
A+B\ Problem
A+B Problem的程序的复杂度小于
O
(
1
)
O(1)
O(1)!
caijiZYC
\texttt{caijiZYC}
caijiZYC不愧是一个菜鸡!这么傻逼的东西都能瞎扯出来!
本文纯属搞笑,请勿当真!