# preface

It seems that the person described in the background of each topic is a role in a certain film. It seems that it is very tragic (emotional).

Then I only know T1 berries. It's really miserable...

# T1 berry conscience

## Problem solving ideas

First, the answer is only related to the sum of \ (w \), so the problem becomes to find the size of each group and the number of corresponding schemes for a point.

In the examination room, you want to enumerate the size of the group, and then preprocess the scheme number of \ (n \) numbers divided into \ (m \) non empty sets.

At first, I thought about the partition method, which was obviously wrong. Then I tried DP calculation, and there was \ (f_{i,j}=f_{i-1,j}\times j+f_{i-1,j-1} \)

I've been thinking about the fast power of the matrix. After watching it for a long time, I found that these TM two dimensions, I'm a ghost!!

Only after the test did I know that this is the second kind of Stirling number, and then I found that this thing can calculate the value of a row or a column by NTT. I'm shallow...

The practice of official problem solving is very different. For a pair of \ (u,v \), when they are divided into a group, there will be more contribution of \ (w_u+w_v \).

Then the answer is \ (\ sum \ limits {I = 1} ^ n w_i) \ times (\; {n \ brace K} + (n-1) \ times {n-1 \ brace K} \;) \)

It is found that the following can be directly excluded:

$\displaystyle{n \brace k}=\frac{1}{k!}\sum_{i=0}^k(-1)^i \binom{k}{i}(k-i)^n$

Then the linear sieve of \ (\ mathcal{O}(n) \) or the fast power of \ (\ mathcal{O}(nlogn) \).

## code

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"RP++"<<endl
using namespace std;
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=1e6+10,M=2e3+10,mod=998244353;
int n,m,ans,base,fac[N],ifac[N] ;
int power(int x,int y,int p=mod)
{
int temp=1;
while(y)
{
if(y&1) temp=temp*x%p;
x=x*x%p; y>>=1;
}
return temp;
}
int C(int x,int y){return fac[x]*ifac[y]%mod*ifac[x-y]%mod;}
int STL(int x,int y)
{
int temp=0;
for(int i=0,bas=1;i<=y;i++,bas=-bas) temp=(temp+bas*C(y,i)*power(y-i,x)%mod+mod)%mod;
return temp*ifac[y]%mod;
}
#undef int
int main()
{
#define int long long
freopen("ichigo.in","r",stdin); freopen("ichigo.out","w",stdout);
ifac[n]=power(fac[n],mod-2); for(int i=n-1;i>=1;i--) ifac[i]=ifac[i+1]*(i+1)%mod;
printf("%lld",base*(STL(n,m)%mod+STL(n-1,m)%mod*(n-1)%mod)%mod);
return 0;
}


# I've run out of pears

## Problem solving ideas

A direct DP is the shortest time to buy \ (j \) items in \ (I \) stores before \ (f_{i,j} \).

It is found that when \ (a_i \) is not 0, the growth is exponential, so each transfer only needs \ (log \) times.

Then, handle the case where \ (a_i \) is 0, and directly maintain a prefix and binary.

There are some small details in the code implementation.

## code

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"RP++"<<endl
using namespace std;
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=2e5+10;
int n,m,ans,pos,lim,f[N],pre[N];
struct Node{int a,b;}s[N];
bool comp(Node x,Node y){x.b++;y.b++;if(x.b*y.a!=y.b*x.a)return x.b*y.a<y.b*x.a;return x.b<y.b;}
#undef int
int main()
{
#define int long long
freopen("eriri.in","r",stdin); freopen("eriri.out","w",stdout);
f[0]=0; sort(s+1,s+n+1,comp); pos=n+1;
for(int i=1;i<=n;i++) if(!s[i].a){pos=i;break;}
for(int i=1;i<=n;i++) s[i].b+=s[i].a+1,s[i].a++;
for(int i=pos;i<=n;i++) pre[i]=pre[i-1]+s[i].b;
for(int i=1;i<pos;i++)
for(int j=min(i,lim);j>=1;j--)
if(f[j-1]<=m) f[j]=min(f[j],f[j-1]*s[i].a+s[i].b);
for(int i=0;i<=min(n,lim);i++)
{
if(f[i]>m) continue;
int l=pos,r=n,temp=-1;
while(l<=r)
{
int mid=(l+r)>>1;
if(pre[mid]<=m-f[i]) temp=mid,l=mid+1;
else r=mid-1;
}
ans=max(ans,i+((~temp)?temp-pos+1:0));
}
printf("%lld",ans);
return 0;
}


# T3 regiment, but

## Problem solving ideas

A wonderful question.

Let \ (p(i) \) represent the number of schemes for \ (i \) rockfill \ (p(i)=(2^n-1)^{\underline{i} \).

Let \ (f(n) \) represent the number of schemes that \ (n \) will fail first. Consider adding a pile of stones equal to the XOR and sum of \ (i-1 \) after \ (i-1 \).

That is \ (p(n-1) \), but if the exclusive or sum of \ (i-1 \) rockfill is already 0, it is obviously illegal and needs to be subtracted.

In another case, the XOR sum of \ (i-2 \) stones is 0, and two new piles of the same stones are added. Obviously, it is also impossible and need to be subtracted.

So there is:

$f(i)=p(i-1)-f(i-1)-f(i-2)\times(i-1)\times(2^n-i+1)$

Direct recursion, and then subtract the total number of schemes.

## code

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"RP++"<<endl
using namespace std;
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=1e7+10,mod=1e9+7;
int n,p[N],p2[N],f[N];
#undef int
int main()
{
#define int long long
freopen("yui.in","r",stdin); freopen("yui.out","w",stdout);
p[0]=1; for(int i=1;i<=n;i++) p[i]=p[i-1]*(p2[n]-i)%mod;
for(int i=3;i<=n;i++) f[i]=(p[i-1]-f[i-1]-(i-1)*f[i-2]%mod*(p2[n]-i+1)%mod+2*mod)%mod;
printf("%lld",(p[n]-f[n]+mod)%mod);
return 0;
}


# T4 seven negative me

## Problem solving ideas

The optimal strategy is that we evenly distribute all values into a complete graph, which can be proved by the adjustment method.

Then, direct enumeration is unacceptable for \ (2^n \). Consider \ (meet\;in\;the\;middle \)

So enumerate the complete graph in the front \ (\ frac{n}{2} \), and then look at its edge connection for the next \ (\ frac{n}{2} \).

After preprocessing, \ (\ frac{n}{2} \) points, the number of complete graphs contained in all point sets.

Then enumerate the point sets of the first \ (\ frac{n}{2} \) points, and then look at their union and combination of the edges of the last \ (\ frac{n}{2} \).

There seems to be a detail wrong in the code, but the wrong point is less than 20. I directly... Combination fist??

## code

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"RP++"<<endl
using namespace std;
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
const int N=50;
int n,m,m1,m2,all,maxn,e[N],f[1<<20];
#undef int
int main()
{
#define int long long
freopen("nanami.in","r",stdin); freopen("nanami.out","w",stdout);
for(int sta=1;sta<(1ll<<m1);sta++)
{
int sum=__builtin_popcount(sta); if(sum<=maxn) continue;
for(int i=1;i<=m1;i++) if((sta>>i-1)&1) if((e[i]&sta)!=(sta^(1ll<<i-1))) goto X;
maxn=max(maxn,sum);X:;
}
if(n<=20) printf("%.6lf",(1.0*(maxn*(maxn-1)/2))*(1.0*all)/(1.0*maxn)*(1.0*all)/(1.0*maxn)),exit(0);
for(int sta=1;sta<(1ll<<m2);sta++)
{
int sum=__builtin_popcount(sta);
for(int i=1;i<=m2;i++) if((sta>>i-1)&1) if(((e[i+m1]>>m1)&sta)!=(sta^(1ll<<i-1))) goto Y;
f[sta]=sta; maxn=max(maxn,sum); Y:;
}
for(int sta=0;sta<(1ll<<m2);sta++)
{
int U=(1ll<<m2)-1,sum=__builtin_popcount(sta);
for(int i=1;i<=m2;i++) if((sta>>i-1)&1) U&=e[i+m1]>>m1;
if(!U&&sum!=1) continue;
for(int i=1;i<=m2;i++)
if((((sta>>i-1)&1)^1))
if((((e[i+m1]>>m1)&sta)==sta&&(U&(1ll<<i-1)))){if(__builtin_popcount(f[sta|(1ll<<i-1)])<sum+1) f[sta|(1ll<<i-1)]=f[sta]|(1ll<<i-1);}
else if(__builtin_popcount(f[sta|(1ll<<i-1)])<sum) f[sta|(1ll<<i-1)]=f[sta];
}
for(int sta=1;sta<(1ll<<m1);sta++)
{
int U=(1<<m2)-1,sum=__builtin_popcount(sta);
for(int i=1;i<=m1;i++) if((sta>>i-1)&1) if((e[i]&sta)!=(sta^(1ll<<i-1))) goto Z;
for(int i=1;i<=m1;i++) if((sta>>i-1)&1) U&=e[i]>>m1;
maxn=max(maxn,sum+__builtin_popcount(f[U])); Z:;
}
printf("%.6lf",(1.0*(maxn*(maxn-1)/2))*(1.0*all)/(1.0*maxn)*(1.0*all)/(1.0*maxn));
return 0;
}


Posted by hannah415 on Fri, 29 Oct 2021 03:59:20 -0700