1 条题解
-
0
自动搬运
来自洛谷,原作者为

stardust_Ray
无论前路如何,我都不会后悔与你的相遇搬运于
2025-08-24 22:26:32,当前版本为作者最后更新于2024-10-04 21:32:35,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
首先考虑如何存储向量。关注到向量与向量之间的操作是每一维分开的,所以我们存储一个多项式表示每一维上经过操作后与 的对应维上的对应关系。三种双目运算和取负、平方都对应多项式上的运算,只有折叠操作特殊。
对于折叠操作,我们预处理每一个幂次 的 ,然后折叠操作也是可以在多项式次数内完成的。
用多项式存储看起来很错,因为正常情况下会被卡到 次(全是平方操作)。但是关注到题目中给定了复杂度这一定义,与多项式的次数完全相等。因为复杂度不超过 ,所以用多项式存只用存 次的系数,暴力乘法即可。
时间复杂度 ,其中 是运算式的复杂度。
代码细节较多,主要在于:
- 取负这一操作要与减法操作区分开来。
- 对于单目运算符计算之前要把取负都先算掉。
Code:
#include<bits/stdc++.h> #define For(i,j,k) for(int i=(j);i<=(k);++i) #define ForDown(i,j,k) for(int i=(j);i>=(k);--i) #define Debug(fmt, args...) fprintf(stderr,"(function %s, line #%d): " fmt,__func__,__LINE__,##args),fflush(stderr) #define debug(fmt, args...) fprintf(stderr,fmt,##args),fflush(stderr) #define within : #define LJY main using namespace std; typedef long long ll; const int N=1e5+5,mod=1e9; mt19937 rnd(chrono::system_clock::now().time_since_epoch().count()); inline int read(){ char ch=getchar();int x=0,f=1; while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); return x*f; } // -----------------template------------------- int n;ll a[N],p[N],sum[11]; char s[N];int m; struct Poly{ ll a[11]; Poly(){For(i,0,10) a[i]=0;} Poly(int x){For(i,1,10) a[i]=0;a[0]=x;} ll& operator[](int x){return a[x];} ll sum(){ll res=0;For(i,0,10) res=(res+a[i]*::sum[i])%mod;return res;} // 计算折叠的答案 }; int add(int x,int y){x+=y;if(x>=mod) return x-mod;else return x;} int suc(int x,int y){x-=y;if(x<0) return x+mod;else return x;} Poly operator+(Poly a,Poly b){For(i,0,10) a[i]=add(a[i],b[i]);return a;} Poly operator-(Poly a,Poly b){For(i,0,10) a[i]=suc(a[i],b[i]);return a;} Poly operator*(Poly a,Poly b){Poly c;For(i,0,10) For(j,0,10-i) c[i+j]=(c[i+j]+a[i]*b[j])%mod;return c;} //---------------少项式------------------- stack<Poly>val; stack<char>op; void flatMinus(){ // 每次运算前把取负给做掉 while(!op.empty()&&op.top()=='-'){ auto p=val.top();val.pop(); val.emplace(Poly()-p);op.pop(); } } void getCalc(){ // 计算 val 的前两项和 op 中的第一项运算后的结果 char t=op.top();op.pop(); Poly x=val.top();val.pop(); Poly y=val.top();val.pop(); if(t=='+') x=x+y; else if(t=='-') x=x-y; else if(t=='*') x=x*y; else assert(0); val.emplace(x); } void emplace_op(char x){flatMinus();op.emplace(x);} void emplace_val(Poly x){ val.emplace(x); if(!op.empty()&&op.top()!=')') getCalc(); } signed LJY(){ n=read();For(i,1,n) a[i]=read(); For(i,1,n) p[i]=1;sum[0]=n; For(i,1,10){ For(j,1,n) p[j]=p[j]*a[j]%mod; For(j,1,n) sum[i]=add(sum[i],p[j]); // 预处理幂次和 }scanf("%s",s+1);m=strlen(s+1); Poly X;X[1]=1;op.emplace(')'); ForDown(i,m,1){ if(s[i]=='X') emplace_val(X); else if(s[i]=='N') emplace_val(n); else if(isdigit(s[i])){ ll sp=0,pw=1;int j=i; while(j&&isdigit(s[j])){ sp=sp+pw*(s[j]-'0'); j--;pw=pw*10%mod; }emplace_val(sp);i=j+1; } else if(s[i]=='/'){ flatMinus();Poly x=val.top();val.pop(); emplace_val(x.sum());i--; }else if(s[i]==':'){ flatMinus(); Poly x=val.top();val.pop(); emplace_val(x*x);i--; }else if(s[i]==')') op.emplace(')'); else if(s[i]=='('){ // 去掉一层括号 flatMinus(),op.pop(); if(!op.empty()&&op.top()!=')') getCalc(); } else emplace_op(s[i]); }flatMinus();printf("%d\n",val.top()[0]); return 0; }
- 1
信息
- ID
- 6234
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者