• HDU 7066


    题面传送门

    提供一种不同于官方题解、需要的操作次数比官方题解多(官方题解大概是 (2 imes 16),我这大概是 (3 imes 16)),但能通过此题的做法。

    首先我们考虑一个暴力,我们设一个阈值 (B=2^k)​​​​,然后我们考虑预处理出 (1sim B)​​​ 中所有数,即,先一遍 p1,然后每次 dup 一遍,然后调用 add 指令给栈顶上的数加 (1)(显然此时 (1) 在栈中),如此操作 (B-1) 次即可让 (1sim B) 中所有数都在栈中。然后再新开一个元素表示答案,然后我们就每 (k) 个元素一块,从高位开始,每次乘以 (2^k)(由于 (2^k)​ 此时已经在栈中,直接调用 mul 指令即可),然后取出这 (k) 位表示的数,调用 add 指令累加到答案中即可,不难发现这样操作次数为 (2(B+dfrac{64}{k})) 级别的,取 (k=4)(B=16) 时最优。

    但这样需要 (4 imes 16) 次操作,无法卡过本题 (50) 次的限制,考虑优化,注意到本题还有一个 sub 命令我们没有调用,因此我们考虑这样一件事情,我们第一部分只预处理出 (1sim 8) 附加上 (16),这样我们第二部分时,假设我们目前处理的这 (k) 位值为 (v),那么如果 (vle 7),显然 (v) 此时已经在栈中,我们就直接用 add 命令将 (v)​ 加到栈顶元素上去即可,但如果 (vge 8)​ 就不太好直接处理了。​一个很直观的想法是,我们直接加 (16),然后减掉该减的部分,但这样还是会卡成 (4 imes 16),样例 (N=2^{64}-1=18446744073709551615) 都过不了,不过注意到在上一步中我们已经乘了个 (16),因此我们考虑在上一轮操作中“预测未来”,即,如果下一轮表示的数 (ge 8) 那么我们就让这轮中最后四位表示的数变成 (v+1),否则直接调到 (v) 即可,这样就省去了那个 (+16)​ 的操作了。这样操作次数就是 (3 imes 16) 级别的了。

    还有一些地方需要卡卡,否则可能会出现 (51) 次操作的悲催情况。

    u1s1 这题操作次数卡得是真的紧,下面这份代码中操作次数的上限就是 (50),在 (n=2^{63}-1) 处取到:

    void solve(){
    	u64 x;scanf("%llu",&x);
    	printf("p1
    ");
    	for(int i=2;i<=8;i++){
    		printf("dup
    ");
    		printf("add %d
    ",i-1);
    	} printf("dup
    add 1
    ");
    	int need=(x>>60&15)+((x>>56&15)>=8);
    	if(!need) printf("p1
    sub 9
    ");
    	else if(need==1) printf("p1
    ");
    	else if(1<need&&need<=9){
    		printf("p1
    add %d
    ",11-need);
    	} else if(need>9){
    		printf("dup
    ");
    		if(need!=16) printf("sub %d
    ",10-(16-need));
    	} printf("mul 1
    ");
    	for(int i=14;~i;i--){
    		int v1=(x>>(i<<2)&15),v2=(!i)?0:(x>>(i-1<<2)&15);
    		if(v1<8&&v2<8){
    			if(v1) printf("add %d
    ",10-v1);
    		} else if(v1<8&&v2>=8){
    			printf("add %d
    ",9-v1);
    		} else if(v1>=8&&v2<8){
    			printf("sub %d
    ",10-(16-v1));
    		} else {
    			if(v1^15) printf("sub %d
    ",11-(16-v1));
    		} if(i) printf("mul 1
    ");
    	} printf("end
    ");
    }
    int main(){
    	int qu;scanf("%d",&qu);
    	while(qu--) solve();
    	return 0;
    }
    /*
    7
    15
    16
    16843009
    1061109567
    1152921504606846975
    1152921504606846976
    2305843009213693951
    */
    
  • 相关阅读:
    iType.js仿输入文字效果
    css上下左右居中
    js的几种继承方式
    jquery ajax跨越
    js构造函数+原型
    less基础引用
    vw单位相关
    移动端适配(rem单位定义方法)
    第二周 day2 python学习笔记
    第一周 day1 Python学习笔记
  • 原文地址:https://www.cnblogs.com/ET2006/p/hdu-7066.html
Copyright © 2020-2023  润新知