标签:序列 科技 += 意思 区域 int swap har amp
#include<iostream> #include<cstdio> using namespace std; typedef long long ll; const int N=(1<<21)+10; double x; int n,top,p[N]; char s[N]; inline int rd(){ int x=0;char c=getchar();bool f=0; while(!isdigit(c)){if(c==‘-‘)f=1;c=getchar();} while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();} return f?-x:x; } ll gcd(ll x,ll y){if(x<0)x=-x;if(y<0)y=-y;return y?gcd(y,x%y):x;} struct fs{ ll x,y; fs operator +(const fs &b)const{ ll xx=x*b.y+y*b.x,yy=y*b.y*2; ll g=gcd(yy,xx); xx/=g;yy/=g; return fs{xx,yy}; } fs operator -(const fs &b)const{ ll xx=x*b.y-y*b.x,yy=y*b.y*2; ll g=gcd(yy,xx); xx/=g;yy/=g; return fs{xx,yy}; } }dp[N]; void dfs(int num,int x){ if(num>n)return; p[++top]=x|(1<<num-1); dfs(num+1,x|(1<<num-1));dfs(num+1,x); } int main(){ n=rd(); for(int i=0;i<(1<<n);++i){ int o=0;scanf("%s%lf",s+1,&x); for(int j=1;j<=n;++j){ o<<=1;o|=(s[j]==‘+‘?1:0); } if(x>0)dp[o].x=(int)(x*100+0.1);//因为要向0取整,所以要判断正负 else dp[o].x=(int)(x*100-0.1); dp[o].y=100; ll g=gcd(dp[o].x,dp[o].y); dp[o].x/=g;dp[o].y/=g; } for(int i=(1<<n-1);i>=1;i>>=1) for(int j=0;j<(1<<n);j+=(i<<1)) for(int k=0;k<i;++k){ fs x=dp[k+j],y=dp[k+i+j]; dp[k+j]=y-x;dp[k+i+j]=x+y; } for(int i=0;i<(1<<n);++i){ int x=i,l=0,r=(1<<n)-1; while(l!=r){ int mid=(l+r)>>1; if(x&1)r=mid;else l=mid+1;x>>=1; } if(l<i)swap(dp[l],dp[i]); } dfs(1,0); for(int i=0;i<(1<<n);++i){ int x=p[i]; if(!dp[x].x)continue; if(dp[x].y<0)dp[x].y=-dp[x].y,dp[x].x=-dp[x].x; if(dp[x].y!=1) printf("%lld/%lld ",dp[x].x,dp[x].y); else printf("%lld ",dp[x].x); for(int j=1;j<=n;++j)if(x&(1<<j-1))printf("x%d",j); printf("\n"); } return 0; }
标签:序列 科技 += 意思 区域 int swap har amp
原文地址:https://www.cnblogs.com/ZH-comld/p/10164411.html