[luogu1737]旷野大计算

(以下题解仅描述方法,具体实现参考代码)

任务1

限制:$6$个

利用分配律优化即可

任务2

限制:$6$个

利用$17=2^{4}+1$优化即可

任务3

限制:$6$个

当$|x|$足够大时,$S(x)$仅取决于$x$的正负性

根据此性质,有$f_{1}(x)=S(2^{\inf_{1}}x)=\begin{cases}1&x>0\\0.5&x=0\\0&x<0\end{cases}$($2$个)

关于$\inf_{1}$,即要求$\frac{1}{1+e^{\frac{2^{\inf_{1}}}{10^{9}}}}\le 10^{-100}$(注意到$S(x)+S(-x)=1$),解得${\inf_{1}}\ge 38$

任务4

限制:$14$个

当$|x|\le 10^{-50}$时,在$x=0$处泰勒展开,可得$S(x)=\frac{1}{4}x+\frac{1}{2}$

用"足够大/小"区分正/负,有$f_{2}(x)=2^{\inf_{2}}f_{1}(x+{\rm eps})=\begin{cases}2^{\inf_{2}}&x\ge 0\\0&x<0\end{cases}$($4$个)

在此基础上,有$f_{3}(x)=x+f_{2}(x)-2^{\inf_{2}+1}\left(S\big(f_{2}(x)+\frac{x}{2^{\inf_{2}-2}}\big)-0.5\right)=|x|$($12$个)

关于${\rm eps}$,即要求${\rm eps}<10^{-9}$,可取$10^{-10}$(另外,这会修改$\inf_{1}$的条件,解得$\inf_{1}\ge 42$)

关于$\inf_{2}$,即要求$\begin{cases}\frac{10^{9}}{2^{\inf_{2}-2}}\le 10^{-50}\\10^{-90}2^{\inf_{2}}<10^{-9}\end{cases}$,解得$\inf_{2}\in [198,269]$

任务5

限制:$95$个

每次$\times 2+x$即可,并在最高位仅输入,即$1+3\times 31+1=95$个

任务6

限制:$190$个

从大到小枚举$i\in [0,32)$,第$i$位即$f_{1}(x-2^{i}+{\rm eps})$,并用$x$减去$2^{i}\times $即可

$f_{1}$的左移可以仅进行一次,并在最低位仅右移输出,即$2+6\times 31+2=190$个

任务7

限制:$605$个

结合前两个任务,问题即需实现单个$0,1$的异或

仅需在相加后为$2$时减$2$,有$f_{6}(x)=x-2\times f_{1}(x-2+{\rm eps})=\begin{cases}x-2&x=2\\x&x=0,1\end{cases}$($6$个)

综上,即$2+(190-33)\times 2+7\times 32+(95-33)+1=603$个

任务8

限制:$7$个

取$x_{0}$满足$S'(x_{0})=\frac{1}{10}$,解得$e^{-x_{0}}=4\pm \sqrt{15}$

不妨取$4-\sqrt{15}$,即$x_{0}=\ln (4+\sqrt{15}),S(x_{0})=\frac{5+\sqrt{15}}{10}$

当$|x-x_{0}|\le 10^{-50}$,在$x=x_{0}$处泰勒展开,即$S(x)=\frac{x-x_{0}}{10}+S(x_{0})$

在此基础上,有$f_{7}(x)=2^{\inf_{2}}\left(S(\frac{x}{2^{\inf_{2}}}+x_{0})-S(x_{0})\right)=\frac{x}{10}$($5$个)

任务9

限制:$3000$个

对于两数$x,y$,考虑在$x>y$时交换两数,等价于$\begin{cases}x'=x+\min(y-x,0)\\y'=y-\min(y-x,0)\end{cases}$

仅需稍微改动$f_{3}$,有$f_{8}(x)=2^{\inf_{2}+1}\left(S\big(f_{2}(x)+\frac{x}{2^{\inf_{2}-1}}\big)-0.5\right)-f_{2}(x)=\min(x,0)$($11$个)

在此基础上,交换两数即$16$个,用冒泡排序实现,即$16+{16\choose 2}\times 16+16=1952$个

另外,用双调排序实现(具体参考这里),仅需$50$次交换,即$16+50\times 16+16=1312$个

任务10

限制:$2000$个

关于乘法,将其中一个数按二进制拆分,即需求形如$p\times 2^{i}\times x$的值

仅需稍微改动$f_{2}$和$f_{3}$,有$\begin{cases}f_{9}(x)=(p-1)2^{\inf_{2}+i-1}\\f_{10}(x)=2^{\inf_{2}+i}\left(S\big(f_{9}(x)+\frac{x}{2^{\inf_{2}-2}}\big)-0.5\right)-f_{9}(x)=p\times 2^{i}\times x\end{cases}$($9$个)

关于取模,考虑从高位到低位依次求解,取$p=f_{1}(x-2^{i}m+{\rm eps})$并统一取负&左移优化即可

综上,即$4+(190-33)+(10\times 31+9)+14\times 64+2=1378$个

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define LL __int128
  4 #define mid (l+r>>1)
  5 const int inf1=50;
  6 const int inf2=200;
  7 const string eps="0.0000000001";
  8 const string feps=".9999999999";
  9 const string x10="2.063437068895560546727281172620131871456591449883392499836032692765902842847409911780353006";
 10 const string Sx10="0.887298334620741688517926539978239961083292170529159082658757376611348309193697903351928738";
 11 const string Pw="112589.9906842624";
 12 int T,n,a[32],b[32];string pw[32];
 13 void init(){
 14     for(int i=0;i<32;i++){
 15         for(LL j=((LL)1<<inf1+i)-112590;j;j/=10)pw[i]=(char)(j%10+'0')+pw[i];
 16         pw[i]="-"+pw[i]+".0093157376";
 17     }
 18 }
 19 void P(string a){
 20     n++,printf("%s\n",a.c_str());
 21 }
 22 void P(string a,int x){
 23     P(a+" "+to_string(x));
 24 }
 25 void P(string a,int x,int y){
 26     P(a+" "+to_string(x)+" "+to_string(y));
 27 }
 28 void P(string a,int x,string b){
 29     P(a+" "+to_string(x)+" "+b);
 30 }
 31 void f1(int m){//2
 32     P("<",m,inf1),P("S",n);
 33 }
 34 void f2(int m){//4
 35     P("C",m,eps),f1(n),P("<",n,inf2);
 36 }
 37 void f3(int m){//12
 38     f2(m),P(">",m,inf2-2),P("+",n-1,n),P("S",n),P("C",n,"-0.5"),P("<",n,inf2+1),P("-",n),P("+",m,n-6),P("+",n-1,n);
 39 }
 40 void f4(int *a){//62
 41     int m=a[31];
 42     for(int i=30;i>=0;i--)P("<",m,1),P("+",a[i],n),m=n;
 43 }
 44 void f5(int m,int *a){//157
 45     P("<",m,inf1),m=n;
 46     for(int i=31;i;i--)P("C",m,pw[i]),P("S",n),a[i]=n,P("<",n,inf1+i),P("-",n),P("+",m,n),m=n;
 47     P(">",m,inf1),a[0]=n;
 48 }
 49 void f6(int m){//6
 50     P("C",m,"-1"+feps),f1(n),P("<",n,1),P("-",n),P("+",m,n);
 51 }
 52 void f7(int m){//5
 53     P(">",m,inf2),P("C",n,x10),P("S",n),P("C",n,"-"+Sx10),P("<",n,inf2);
 54 }
 55 void f8(int m){//11
 56     f2(m),P(">",m,inf2-1),P("+",n-1,n),P("S",n),P("C",n,"-0.5"),P("<",n,inf2+1),P("-",n-5),P("+",n-1,n);
 57 }
 58 void solveB(int l,int r){
 59     if (l==r)return;
 60     for(int i=l;i<=mid;i++){
 61         int j=i+mid-l+1,x=a[i],y=a[j];
 62         P("-",x),P("+",y,n),f8(n),P("+",x,n),a[i]=n,P("-",n-1),P("+",y,n),a[j]=n;
 63     }
 64     solveB(l,mid),solveB(mid+1,r);
 65 }
 66 void solve(int l,int r){
 67     if (l==r)return;
 68     solve(l,mid),solve(mid+1,r);
 69     reverse(a+mid+1,a+r+1),solveB(l,r);
 70 }
 71 void f9(int m,int p,int i){//2
 72     P("C",p,"-1"),P("<",n,inf2+i-1);
 73 }
 74 void f10(int m,int p,int i){//9
 75     f9(m,p,i),P(">",m,inf2-2),P("+",n-1,n),P("S",n),P("C",n,"-0.5"),P("<",n,inf2+i),P("-",n-5),P("+",n-1,n);
 76 }
 77 int main(){
 78     scanf("%d",&T),init();
 79     if (T==1)P("I"),P("I"),P("+ 1 2"),P("- 3"),P("< 4 1"),P("O 5");
 80     if (T==2)P("I"),P("< 1 4"),P("+ 1 2"),P("- 3"),P("S 4"),P("O 5");
 81     if (T==3)P("I"),f1(1),P("< 3 1"),P("C 4 -1"),P("O 5");
 82     if (T==4)P("I"),f3(1),P("O 13");
 83     if (T==5){
 84         for(int i=31;i>=0;i--)P("I"),a[i]=n;
 85         f4(a),P("O",n);
 86     }
 87     if (T==6){
 88         P("I"),f5(1,a);
 89         for(int i=31;i>=0;i--)P("O",a[i]);
 90     }
 91     if (T==7){
 92         P("I"),P("I"),f5(1,a),f5(2,b);
 93         for(int i=0;i<32;i++)P("+",a[i],b[i]),f6(n),a[i]=n;
 94         f4(a),P("O",n);
 95     }
 96     if (T==8)P("I"),f7(1),P("O 6");
 97     if (T==9){
 98         for(int i=0;i<16;i++)P("I"),a[i]=n;
 99         if (0){//冒泡排序 
100             for(int i=0;i<16;i++)
101                 for(int j=15;j>i;j--){
102                     int x=a[j-1],y=a[j];
103                     P("-",x),P("+",y,n),f8(n),P("+",x,n),a[j-1]=n,P("-",n-1),P("+",y,n),a[j]=n;
104                 }
105         }
106         else solve(0,15);//双调排序
107         for(int i=0;i<16;i++)P("O",a[i]);
108     }
109     if (T==10){
110         P("I"),P("I"),P("I"),P("-",3),f5(1,a),f10(2,a[0],inf1);
111         int m=n;
112         for(int i=1;i<32;i++)f10(2,a[i],inf1+i),P("+",m,n),m=n;
113         for(int i=63;i>=0;i--)P("<",4,inf1+i),P("+",m,n),P("C",n,Pw),P("S",n),f10(4,n,inf1+i),P("+",m,n),m=n;
114         P(">",m,inf1),P("O",n);
115     }
116     return 0;
117 }
View Code

 

posted @ 2022-08-19 14:56  PYWBKTDA  阅读(79)  评论(0编辑  收藏  举报