# 2021.10.29 test summary [sprint NOIP simulation 18]

This question is true. Have fun

Give me the test

# T1 berry conscience

I came to see you dressed up like you like, Guang, no, da, darling

It is not difficult to see that the value of \ (w \) has nothing to do with its number of contributions. Considering each scheme, it must have \ (1 \) contribution and additional contribution combined with other elements, including

$ans=(\sum_{i=1}^nw_i)\times\begin{Bmatrix}n\\k\end{Bmatrix}+(\sum_{u!=v}(w_u+w_v))\begin{Bmatrix}n-1\\k\end{Bmatrix}$

$ans=(\sum_{i=1}^nw_i)\times(\begin{Bmatrix}n\\k\end{Bmatrix}+(n-1)\begin{Bmatrix}n-1\\k\end{Bmatrix})$

Where \ (\ begin{Bmatrix}n\k\end{Bmatrix} \) represents the Stirling number of the second type, and the number of schemes that divide \ (n \) elements into \ (k \) non empty sets.

have

$\begin{Bmatrix}n\\k\end{Bmatrix}=\frac{1}{k!}\sum_{i=0}^k(-1)^i\binom{k}{i}(k-i)^n$

Linearly screen out all \ (k-i \) to the power of \ (n \) and \ (n-1 \).

$$code:$$

T1
#include<bits/stdc++.h>
#define int long long
using namespace std;

namespace IO{
typedef long long LL;
LL x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*f;
}
void write(int x,char sp){
char ch[20]; int len=0;
if(x<0) x=-x,putchar('-');
do{ ch[len++]=x%10+'0'; x/=10; }while(x);
for(int i=len-1;~i;i--) putchar(ch[i]); putchar(sp);
}
void ckmin(int& x,int y){ x=x<y?x:y; }
void ckmax(int& x,int y){ x=x>y?x:y; }
} using namespace IO;

const int NN=1000010,mod=998244353;
int n,k,cnt,sum,tmp1,tmp2,f[NN],g[NN],pri[NN];
bool vis[NN];

namespace Combination{
int inv[NN],fac[NN];
int C(int x,int y){ return x<0||y<0||x<y?0:fac[x]*inv[y]%mod*inv[x-y]%mod; }
int qpow(int a,int b){
int res=1;
for(;b;b>>=1){
if(b&1) res=res*a%mod;
a=a*a%mod;
}
return res;
}
void init(){
fac[0]=inv[0]=1;
for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
inv[n]=qpow(fac[n],mod-2);
for(int i=n-1;i;i--) inv[i]=inv[i+1]*(i+1)%mod;
}
} using namespace Combination;

void get(){
f[1]=1; g[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]) pri[++cnt]=i,f[i]=qpow(i,n),g[i]=qpow(i,n-1);
for(int j=1;j<=cnt&&pri[j]*i<=n;i++){
vis[pri[j]*i]=1;
f[pri[j]*i]=f[pri[j]]*f[i]%mod;
g[pri[j]*i]=g[pri[j]]*g[i]%mod;
if(i%pri[j]==0) break;
}
}
}
signed main(){
freopen("ichigo.in","r",stdin);
freopen("ichigo.out","w",stdout);
for(int i=0;i<=k;i++){
(tmp1+=((i&1)?-1:1)*C(k,i)*f[k-i]%mod+mod)%=mod;
(tmp2+=((i&1)?-1:1)*C(k,i)*g[k-i]%mod+mod)%=mod;
}
(tmp1*=qpow(fac[k],mod-2))%=mod;
(tmp2*=qpow(fac[k],mod-2))%=mod;
sum=sum*(tmp1+(n-1)*tmp2%mod)%mod;
write(sum,'\n');
return 0;
}


# I've run out of pears

Have I become the first in your heart?

Consider \ (a_i > 0 \) first.

Considering the temporary exchange, for \ (i < j \), calculate the extra time of queuing, and i is better before \ (j \), then

$(a_i\times t+b_i+1)\times a_j<(a_j\times t+b_j+1)\times a_i$

Namely

$(b_i+1)\times a_j<(b_j+1)\times a_i$

According to this relationship, the final answer must be generated by the sorted subsequence. Set the status \ (f_{i,j} \) as the shortest time of \ (j \) elements considering the \ (I \) bit. So there

$f_{i,j}=min(f_{i-1,j},f_{i-1,j-1}+a_i\times(f_{i-1,j-1}+1)+b_i+1)$

Because \ (a_i > 0 \), the time for each selection is at least doubled. The second bit is \ (\ log \) level, and the complexity is no problem.

\After (DP \), consider the elements of \ (a_i=0 \), from childhood to general election.

$$code:$$

T2
#include<bits/stdc++.h>
#define int long long
using namespace std;

namespace IO{
typedef long long LL;
LL x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*f;
}
void write(int x,char sp){
char ch[20]; int len=0;
if(x<0) x=-x,putchar('-');
do{ ch[len++]=x%10+'0'; x/=10; }while(x);
for(int i=len-1;~i;i--) putchar(ch[i]); putchar(sp);
}
void ckmin(int& x,int y){ x=x<y?x:y; }
void ckmax(int& x,int y){ x=x>y?x:y; }
} using namespace IO;

const int NN=200010;
int n,t,ext,ans,tim,dlt[NN],f[NN][50];
vector<int>zro;
struct shop{
int a,b;
bool operator<(const shop& x)const{
return (b+1)*x.a<(x.b+1)*a;
}
}s[NN];

signed main(){
freopen("eriri.in","r",stdin);
freopen("eriri.out","w",stdout);
for(int a,b,i=1;i<=n;i++){
if(!a) zro.push_back(b);
else s[++ext]=(shop){a,b};
}
sort(s+1,s+ext+1); sort(zro.begin(),zro.end());
memset(f,0x3f,sizeof(f)); f[0][0]=0;
for(int i=1;i<=ext;i++)
for(int j=0;j<50;j++){
f[i][j]=f[i-1][j];
if(j&&f[i-1][j-1]<=t)
ckmin(f[i][j],f[i-1][j-1]+1+s[i].b+(1+f[i-1][j-1])*s[i].a);
}
for(int i=0;i<50;i++) if(f[ext][i]<=t){
int k=f[ext][i],res=i;
for(int j:zro){
k+=j+1;
if(k>t) break;
++res;
}
ckmax(ans,res);
}
write(ans,'\n');
return 0;
}


# T3 regiment, but

Tears didn't come out. Because I've cried many times.

Tolerance and exclusion.

Let \ (p_i \) represent the total number of schemes for \ (I \) rockfill, with

$p_i=(2^n-1)^{\underline{i}}$

Let \ (f_i \) indicate the number of schemes in which \ (I \) stone stacking must be defeated first.

When the exclusive or sum of the current \ (i-1 \) rockfill is not zero, if it is not considered that they are different from each other, the last number can always be used to adjust the exclusive or sum to zero. This part of the scheme is \ (p_{i-1}-f_{i-1} \).

Next, let's exclude several identical cases. When the current \ (i-1 \) rockfill has \ (i-2 \) rockfill and the XOR sum is zero, the other two rockfill must be equal. The number of such cases is \ ((i-1)\times(2^n-i+1)\times f_{i-2} \). Position multiplier multiplier.

To sum up,

$f_i=p_{i-1}-f_{i-1}-(i-1)\times(2^n-i+1)\times f_{i-2}$

Linear recurrence is sufficient.

$$code:$$

T3
#include<bits/stdc++.h>
#define int long long
using namespace std;

namespace IO{
typedef long long LL;
LL x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*f;
}
void write(int x,char sp){
char ch[20]; int len=0;
if(x<0) x=-x,putchar('-');
do{ ch[len++]=x%10+'0'; x/=10; }while(x);
for(int i=len-1;~i;i--) putchar(ch[i]); putchar(sp);
}
void ckmin(int& x,int y){ x=x<y?x:y; }
void ckmax(int& x,int y){ x=x>y?x:y; }
} using namespace IO;

const int NN=10000010,mod=1e9+7;
int n,ans,base,p[NN],f[NN];

namespace Combination{
int fac[NN],inv[NN];
int C(int x,int y){ return x<0||y<0||x<y?0:fac[x]*inv[y]%mod*inv[x-y]%mod; }
int qpow(int a,int b){
int res=1;
for(;b;b>>=1){
if(b&1) res=res*a%mod;
a=a*a%mod;
}
return res;
}
void init(){
fac[0]=inv[0]=1;
for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
inv[n]=qpow(fac[n],mod-2);
for(int i=n-1;i;i--) inv[i]=inv[i+1]*(i+1)%mod;
}
} using namespace Combination;

signed main(){
freopen("yui.in","r",stdin);
freopen("yui.out","w",stdout);
for(int i=1;i<=n;i++) p[i]=p[i-1]*(base-i)%mod;
for(int i=3;i<=n;i++)
f[i]=(p[i-1]+mod-f[i-1]+mod-(i-1)*(base-i+1)%mod*f[i-2]%mod)%mod;
ans=(mod+p[n]-f[n])%mod;
write(ans,'\n');
return 0;
}


# T4 seven negative me

Since it's really white, if you don't want it, Mr. Kanda belongs to me.

Conclusion: the final answer is the answer obtained by taking the largest clique in the graph and evenly distributing the point weight.

### Certification mission:

Let \ (u,v \) be two points that are not connected to each other, and let \ (s_, s_, V \) be the sum of weights of points connected to \ (u,v \), then when \ (s_ \ NEQ s_, V \), it is obvious that the weight of one point of \ (u,v \) is \ (0 \)\ (s_, u = s_, V \) can also ensure that the weight of one point of \ (u,v \) is \ (0 \) is an optimal solution. Therefore, there is always one point between two disconnected points that will not be assigned a weight, that is, the final answer will appear in the group.

### Proof of equal distribution:

Set \ (t_i \) as the weight of the \ (I \) point in the group and \ (s \) as the group size, then \ (x = \ sum {I = 1} ^ st_i \) has

$ans=\sum_{u\neq v} t_u\times t_v$

$ans=\frac{x^2-\sum_{i=1}^st_i^2}{2}$

According to the mean inequality, when \ (t_i \) are equal, \ (ans \) takes the maximum value.

### Proven maximum:

Set the cluster size to \ (s \), then

$ans=\frac{s\times(s-1)}{2}\times(\frac{x}{s})^2$

$ans=\frac{(s-1)\times x^2}{2s}=x^2\times(\frac{1}{2}-\frac{1}{2s})$

\The larger the (s \), the closer the \ (\ frac{1}{2s} \) is to \ (0 \), and the larger the answer value.

### To sum up, we can get the top conclusion.

$$meet\;in\;the\;middle$$, find the largest subgroup of all the point sets in the first half, and set the maximum subgroup of the point set \ (s \) as \ (f_s \), and then enumerate the latter half of the point set \ (t \). If \ (t \) is a group and \ (E \) is the intersection of the adjacent points of all the points in \ (t \) in the previous part, then \ (|t|+f_e \) can be the answer.

$$code:$$

T4
#include<bits/stdc++.h>
using namespace std;

namespace IO{
typedef long long LL;
LL x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
return x*f;
}
void write(int x,char sp){
char ch[20]; int len=0;
if(x<0) x=-x,putchar('-');
do{ ch[len++]=x%10+'0'; x/=10; }while(x);
for(int i=len-1;~i;i--) putchar(ch[i]); putchar(sp);
}
void ckmin(int& x,int y){ x=x<y?x:y; }
void ckmax(int& x,int y){ x=x>y?x:y; }
} using namespace IO;

const int NN=45;
int n,m,x,lmt,ans,f[1<<20];
int ef[NN],eb[NN];
double res;

int getnum(int s){
int res=0;
while(s) res+=(s&1),s>>=1;
return res;
}
bool check(int s,bool typ){
for(int i=0;i<lmt;i++) if(s&(1<<i))
if(((s^(1<<i))|ef[i+1+typ*lmt])!=ef[i+1+typ*lmt]) return 0;
return 1;
}

signed main(){
freopen("nanami.in","r",stdin);
freopen("nanami.out","w",stdout);
for(int u,v,i=1;i<=m;i++){
if(u>v) swap(u,v);
if(v<=lmt){
ef[u]|=1<<v-1;
ef[v]|=1<<u-1;
} else if(u>lmt){
ef[u]|=1<<v-1-lmt;
ef[v]|=1<<u-1-lmt;
} else eb[v]|=1<<u-1;
}
for(int i=1;i<(1<<lmt);i++)
if(check(i,0)) ckmax(ans,f[i]=getnum(i));
for(int s=1;s<(1<<lmt);s++)
for(int i=0;i<lmt;i++)
if(!(s&(1<<i))) ckmax(f[s|(1<<i)],f[s]);
for(int s=1;s<(1<<lmt);s++) if(check(s,1)){
int tmp=(1<<lmt)-1;
for(int i=0;i<lmt;i++)
if(s&(1<<i)) tmp&=eb[i+1+lmt];
ckmax(ans,getnum(s)+f[tmp]);
}
res=(1.0*x/ans)*(1.0*x/ans)*(ans-1)*ans/2;
printf("%.6lf\n",res);
return 0;
}


Posted on Fri, 29 Oct 2021 07:22:54 -0400 by wblati