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:
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; inline int read() { 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); n=read(); m=read(); fac[0]=ifac[0]=1; for(int i=1;i<=n;i++) base=(base+read())%mod,fac[i]=fac[i-1]*i%mod; 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; inline int read() { 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); n=read(); m=read(); lim=(int)log2(m)+1; memset(f,0x3f,sizeof(f)); for(int i=1;i<=n;i++) s[i].a=read(),s[i].b=read(); 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:
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; inline int read() { 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); n=read(); p2[0]=1; for(int i=1;i<=n;i++) p2[i]=p2[i-1]*2%mod; 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; inline int read() { 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); n=read(); m=read(); all=read(); m1=n>>1; m2=n-m1; if(n<=20) m1=n; for(int i=1,x,y;i<=m;i++) x=read(),y=read(),e[x]|=1ll<<y-1,e[y]|=1ll<<x-1; 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; }