# [考试反思]0323省选模拟53：常数

T1：数（number）

$dy$原题。思路不难。

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define mod 1000000007
4 #define S 2750001
5 map<int,int>M[S];
6 int fac[S],inv[S],t,n;
7 int qp(int b,int t,int a=1){for(;t;t>>=1,b=1ll*b*b%mod)if(t&1)a=1ll*a*b%mod;return a;}
8 int C(int b,int t){return t<0||t>b?0:1ll*fac[b]*inv[t]%mod*inv[b-t]%mod;}
9 int cal(int n,int v){
10     v=abs(v);
11     if(!n)return v?0:1;
12     if(M[n][v])return M[n][v];int rn=n,rv=v;
13     v+=n*9;int ans=0;n<<=1;
14     for(int i=0;v>=0;++i,v-=10)ans=(ans+(i&1?-1ll:1ll)*C(n,i)*C(v+n-1,n-1))%mod;
15     return M[rn][rv]=(ans+mod)%mod;
16 }
17 int main(){
18     for(int i=fac[0]=1;i<S;++i)fac[i]=1ll*fac[i-1]*i%mod;
19     inv[S-1]=qp(fac[S-1],mod-2);
20     for(int i=S-2;~i;--i)inv[i]=inv[i+1]*(i+1ll)%mod;
21     cin>>t;while(t--){cin>>n;
22         if(n%2==0)cout<<qp(10,n/2)<<endl;
23         else if(n%4==1){
24             int ans=0;
25             for(int i=0;i<5;++i)ans=(ans+cal(n/4,i))%mod;
26             cout<<ans<<endl;
27         }else{
28             int ans=0;
29             for(int i=0;i<5;++i)for(int j=0;j<=9;++j)ans=(ans+cal(n/4,i-j))%mod;
30             cout<<ans<<endl;
31         }
32     }
33 }
View Code

T2：序列

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define S 111111
4 int a[S],n,t,p[S],ans1[S],ans2[S],c,C,c1,c2;
5 void pt(int*a){for(int i=1;i<=n;++i)printf("%d ",a[i]);}
6 priority_queue<int>q; map<int,int>M;
7 void solve(int*A,int s,int t,int o){
8     if(o){
9         int p1=s,p2=s;
10         while(p1<=t||p2<=t){
11             while(p[p1]<=p2&&p1<=t)q.push(-a[p[p1]]),p1+=2;
12             while((p1>t||p2<p[p1])&&p2<=t)A[p2]=-q.top(),q.pop(),p2+=2;
13         }
14     }else{
15         int p1=t,p2=t;
16         while(p1>=s||p2>=s){
17             while(p[p1]>=p2&&p1>=s)q.push(a[p[p1]]),p1-=2;
18             while((p1<s||p2>p[p1])&&p2>=s)A[p2]=q.top(),q.pop(),p2-=2;
19         }
20     }
21 }
22 void work(int t,int*A){
23     c=-1;C=0;for(int i=1;i<=n;++i)if(a[i]&1^t)p[c+=2]=i;else p[C+=2]=i;
24     for(int i=1,d;d=i>=p[i],i<=n;)for(int j=i;;j+=2)if(j>=p[j]^d||j>n){solve(A,i,j-2,d);i=j;break;}
25     for(int i=2,d;d=i>=p[i],i<=n;)for(int j=i;;j+=2)if(j>=p[j]^d||j>n){solve(A,i,j-2,d);i=j;break;}
26 }
27 int main(){
28     cin>>n;
29     for(int i=1;i<=n;++i)scanf("%d",a+i),t+=a[i]&1,M[a[i]]=i;
30     if(n&1)work(t<n-t,ans1),pt(ans1);
31     else{
32         work(0,ans1);work(1,ans2);
33         for(int i=1;i<=n;++i)c1+=abs(i-M[ans1[i]]),c2+=abs(i-M[ans2[i]]);
34         if(c1!=c2)return pt(c1<c2?ans1:ans2),0;
35         for(int i=1;i<=n;++i)if(ans1[i]!=ans2[i]){pt(ans1[i]<ans2[i]?ans1:ans2);break;}
36     }
37 }
View Code

T3：烤仓鼠

$maxsum=(a[1] \times same1) \times (x+d) + ( (a[1] \times (n-same1 ) \times (x+d) + (n-same1 ) \times d )$

（其实应该和$a[i] \times (x+d)$取$min$但是既然$a[i]-a[1] \ge 1$那么明显后面这个界就被前面包含了。

（不必再考虑人与人之间的限制，因为我们在限制组的时候，人的上下界也已经用$[x,x+d]$卡住了，所以组合法人也一定合法）

（也相当于在尽量缩小组间极差使之合法，现在组差一定$\le d$因为最小的也是$a[i] \times (n+d)$。如果有的组超过这个值$+d$那么一定非法）

（这里为了节约常数，不突破下届，可以直接对$mx[n]-mn[n]$取$mn$。因为$n$的下界一定是最大的，而上界又被压平了，所以一定是限制的最紧的）

（其实也一定不会超过$d$，因为上面已经保证了所有组同时下降，就说明，要么是不够让你下降那么多，要么是触及了某些组的下界）

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define S 1111111
4 long long m,n,a[S],sum[S],same1,o[S],R[S],mn[S],mx[S];
5 bool chk(long long d){
6     // MAX_SUM = (a[1]*same1)*(x+d) + [ (a[1]*(n-same1))*(x+d) + (n-same1) * d ]
7     // = a[1]*n*(x+d) + d * (n-same1)
8     // = a[1]*n*x + ( a[1]*n + ( n-same1 ) )*d
9     // MAX >= m
10     // x<= [ m - ( a[1]*n +(n-same1) )*d ]  /  (a[1]*n) {ceil}
11     long long x=max(0.,ceil((m-(1.*a[1]*n+(n-same1))*d)/a[1]/n)),MIN_SUM=sum[n]*x;
12     if(x>m/sum[n])return 0;
13     for(int i=1;i<=n&&MIN_SUM<=m;++i)
14         if( max(a[i]*x,a[n]*x-d) > 1.*a[1]*(x+d)+(a[i]==a[1]?0:d)) return 0;//MIN_GROUP > MAX_GROUP
15         else MIN_SUM+=max((a[n]-a[i])*x-d,0ll);//Can not be less than a[n]*x-d,so add (a[n]*x-d) - (a[i]*x)
16     return MIN_SUM<=m;
17 }
18 void solve(long long d){
19     if(!d){for(int i=1;i<=n;++i)printf("%lld ",m/n);return;}
20     long long x=max(0.,ceil((m-(1.*a[1]*n+(n-same1))*d)/a[1]/n)),tot=0,w,MN=a[1]*(d+x);
21     for(int i=1;i<=n;++i)mn[i]=max(a[i]*x,a[n]*x-d),mx[i]=a[1]*(x+d)+(a[i]!=a[1]?d:0),tot+=mx[i];//init to max
22     for(int i=n;i&&tot!=m;--i)w=min(mx[i]-max(mn[i],MN),tot-m),mx[i]-=w,tot-=w;//make it legel when a[1] is at its max
23     if(d){long long T=min((tot-m)/n,mx[n]-mn[n])/d*d;if(T)for(int i=n;i;--i)mx[i]-=T,tot-=T;}//decrease averangely,still legel
24     MN=min(mx[n]-mn[n],d);//cannot decrease more than d.
25     for(int i=n;i&&tot!=m;--i)w=min(min(mx[i]-mn[i],MN),tot-m),tot-=w,mx[i]-=w;
26     for(int i=n;i&&tot!=m;--i)w=min(mx[i]-mn[i],tot-m),tot-=w,mx[i]-=w;
27     for(int i=1;i<=n;++i)printf("%lld ",mx[R[i]]);
28 }
29 char buffer[S],*s,*t;
32     register int p=0;register char ch=getchar();
33     while(ch<'0'||ch>'9')ch=getchar();
34     while(ch>='0'&&ch<='9')p=(p<<3)+(p<<1)+ch-'0',ch=getchar();
35     return p;
36 }
37 int main(){//freopen("hamster6-1.in","r",stdin);freopen("0.out","w",stdout);
38     cin>>n>>m;
46 }