值得纪念的测试43
记42场考试后终于迎来的rank1,
与大翻盘。(一夜翻身做主人)
长风搏空,远洋浪劲。
革命远未成功,同志仍需努力。
(只是简单题打得好。。。)
#include<bits/stdc++.h> #define F(i,a,b) for(rg int i=a;i<=b;++i) #define rg register #define LL long long #define il inline #define pf(a) printf("%lld ",a) #define phn puts("") using namespace std; /* 1、部分分2、调试信息 */ #define int LL int S,T,a,b; int B[80],top; signed main(){ scanf("%lld%lld%lld%lld",&S,&T,&a,&b); B[0]=1; for(int i=1;T/b>=B[i-1];++i){ B[i]=B[i-1]*b; top=i; } rg int ans=0x3f3f3f3f3f3f3f,w=0,x; for(int i=0;T/S>=B[i]&&i<=top;++i){ w=i; x=T-S*B[i]; if(x%a)continue; x/=a; for(int j=i;~j;--j){ int t=x/B[j]; w+=t; x-=t*B[j]; } if(x)continue; ans=min(ans,w); } printf("%lld\n",ans); } /* g++ 1.cpp -g ./a.out 3 10000000000 4 2 */
#include<bits/stdc++.h> #define F(i,a,b) for(rg int i=a;i<=b;++i) #define rg register #define LL long long #define il inline #define pf(a) printf("%d ",a) #define PF(a) printf("%lld ",a) #define phn puts("") using namespace std; /* 错因: 1:f数组没清0.转移后f[now][]=0; 2:筛约数要判i!=P/i */ const int mod=1e9+7; int n,m,P; LL f[2][5001]; int yue[5005],top,ou[5005],inv[5005]; int G_ou[5005],G_inv[5005]; int a[2002][2002]; il void MO(LL &x){while(x>=mod)x-=mod;} il LL qpow(LL x,int k){LL s=1;for(;k;x=x*x%mod,k>>=1)if(k&1)s=s*x%mod;return s;} map<int,int>mp; il void work(int r){ int x=yue[r],ans=x; for(int i=2;i*i<=x;++i){ if(x%i==0){ ans-=ans/i; while(x%i==0)x/=i; } } if(x>1){ ans-=ans/x; } ou[r]=ans; inv[r]=qpow(ou[r],mod-2); } il LL gcd(LL a,LL b){return b==0?a:gcd(b,a%b);} int main(){ scanf("%d%d%d",&n,&m,&P); int ed=sqrt(P); F(i,1,ed){ if(P%i==0){ yue[++top]=i; if(i*i!=P)yue[++top]=P/i; } } sort(yue+1,yue+top+1); F(i,1,top)mp[yue[i]]=i; F(i,1,top){ work(i); } F(i,1,top){ G_ou[i]=ou[mp[P/yue[i]]]; G_inv[i]=inv[mp[P/yue[i]]]; } F(i,1,top){ F(j,1,top){ a[i][j]=gcd(1ll*yue[i]*yue[j],P); a[i][j]=lower_bound(yue+1,yue+top+1,a[i][j])-yue; // pf(a[i][j]); } // phn; } F(i,1,top)f[1][i]=1; rg int now=1; F(i,1,n-1){ now=i&1; F(j,1,top){ F(k,1,top){ (f[!now][a[j][k]]+=f[now][j]*G_ou[j]%mod*G_ou[k]%mod*G_inv[a[j][k]]%mod)%=mod; } f[now][j]=0; } } now=n&1; // F(i,1,top)PF(f[now][i]);phn; int x,t; F(i,1,m){ scanf("%d",&x); if(x==0)x=P; t=lower_bound(yue+1,yue+top+1,gcd(x,P))-yue; PF(f[now][t]); } phn; } /* g++ 2.cpp -g ./a.out 10 4 24 0 1 2 3 g++ 5.cpp -g ./a.out 10 4 24 0 1 2 3 */
#include<bits/stdc++.h> #define F(i,a,b) for(rg int i=a;i<=b;++i) #define rg register #define LL long long #define il inline #define PF(a) printf("%lld ",a) #define pf(a) printf("%d ",a) #define phn puts("") using namespace std; #define int LL #define N 100010 int n,m,K; LL ans=1e15; int a[N],b[N]; struct node{ int l,r; friend bool operator < (const node &x,const node &y){return x.l<y.l;} }s[N]; int cf[N]; il LL jud(LL o){ // memset(cf,0,sizeof(cf)); LL mx=0,w=0,sum=o; F(i,1,n){ sum+=cf[i]; cf[i]=0; if(a[i]>sum){ if(b[i]>=i){ int u=a[i]-sum; sum+=u;cf[b[i]+1]-=u; w+=u; } else{ mx=max(mx,a[i]-sum); } } } cf[n+1]=0; w+=(o+mx)*K; ans=min(ans,w); return w; } signed main(){ // freopen("1.in","r",stdin); scanf("%lld%lld%lld",&n,&m,&K); F(i,1,n){ scanf("%lld",&a[i]); } rg int l,r; F(i,1,m){ scanf("%lld%lld",&l,&r); s[i]=(node){l,r}; } sort(s+1,s+m+1); rg int p=0,mx=0; F(i,1,n){ while(p<m&&s[p+1].l<=i)mx=max(mx,s[++p].r); b[i]=mx; } l=0;r=1e7+5; int mida,midb,midc; ans=1e15; while(l<r-2){ mida=l+(r-l)/3;midb=r-(r-l)/3; LL wa=jud(mida),wb=jud(midb); // pf(mida);pf(midb);PF(wa);PF(wb);phn;// if(wa<wb)r=midb; else l=mida; } F(i,l,r)jud(i); printf("%lld\n",ans); } /* g++ 3.cpp -g ./a.out 3 3 2 4 12 5 2 2 2 2 2 2 */
T2一些代码实现比较好,要看看。
T1:写十字狮子。
T2:打表,发现规律。
T3:何时贪心。
注:三分写法:
while(l<r-2){
mida=l+(r-l)/3;midb=r-(r-l)/3;
LL wa=jud(mida),wb=jud(midb);
// pf(mida);pf(midb);PF(wa);PF(wb);phn;//
if(wa<wb)r=midb;
else l=mida;
}
F(i,l,r)jud(i);
T1:数据范围1e18,应该是随便搞一搞。
写狮子。
T=S*b^x+a*sigma(b^i);
b^i预处理,
log枚举x,log计算有几个b^i。
是B进制思想。
当左边已确定时,右边也可以确定。
两个细节:
1、i<=x。
(狮子要写变量范围)
2、一个地方while()-=x要写成除法-=A/x*x。否则凭空变慢。
T2:
考试只会暴力n*p^2DP。
最后半小时基本没得分,刚T2不会写,
zj;
打表,发现很多项DP值一样,且与P因数越多(gcd越大)DP值越大。
但是考试不会用,没更进一步思考。
其实不远了。要去大胆猜测。
取模意义下只关注有几个质因子与P相同。(即gcd)
f[i][j],j与P的GCD相同时,f相同。
p^2的DP可优化为(约数个数)^2
1e9内约数个数最大1344
质因子个数超过时与P取min。
实际上是取gcd.
因为是取mod意义下,打表去找关注什么,
在取模意义下, 非约数的部分是等效且不关注的。
感性理解,我也没理解透彻。
转移狮子:
j*k转移到t
f[i+1][t]+=f[i][j]*ou(P/j)*ou(P/k)*(1/ou(P/t));
f含义是单点的。
系数:两个ou是gcd同为j/k的个数。因为转以后要平分到ou(P/t)个上去,所以要除。
T2一些代码实现比较好。
T3:
序列题,区间操作。
类似前两天一道贪心。
本题差不多。贪心最右端点不会变差。
类比之前一道广义差分,那个是异或,区间变单点。
这题区间用不上,但是差分用上了。
(大神们用线段树、树状数组做了{一个变量、一个差分数组}构成的差分能做的事。)
尽量简单化,不要复杂化。简单操作胜过复杂结构。
t那个特殊的,f(使用次数)的函数是单谷的。可以三分。
函数的观察、研究。
然后就三分套贪心了。
T0:
(遇到简单题,一道随便搞一道贪心,只有T2挺难还不会打的暴力然后就rank1了。。。稍水。。。)
考试写了T1T3正解,T2不会只写了暴力。
结果T3数据出锅,全场最高40,
预估240实际180
然额并列rank1了。。。(但我罚时少啊,快结束一直纠结要不要再交一个,想想算了,于是救了我罚时)
1、考前英语课剧困,怕奥赛考试犯困,写了半张卷子,然后睡了不到半截课。
为考试准备了精力(论准备工作)
录卡借的OOO大神的(所以rank1要感谢OOO)
(然额英语作业分数比OOO大神还高)
(然额英语作业还是班rank14)
2、考后:拿到测试点后,大家改完的代码第一个点都一样,都错了,而且比答案小!大脸打完也是。
我们就怀疑数据错了。靠kx的对拍发现果然错了!
重测以后。。。顺利从180升到240了(第一还是并列的)
3、记第一次上台主持考后分享。