2020牛客多校(第六场)

2020牛客暑期多校训练营(第六场)解题报告

 B-Binary Vector

  • 看样例可得f_n=\prod_{i=1}^{n}(1-\frac{1}{2^i}),
  • 答案g_n=f_1 \wedge f_2 \wedge f_3 \wedge.....\wedge f_n,只需要求一次2的逆元就够了

   
   
   
   
  1. #include
  2. using namespace std;
  3. typedef long long LL;
  4. const int mod = 1e9+ 7;
  5. const int N = 2e7+ 10;
  6. LL POW(LL x,LL y)
  7. {
  8. LL ans= 1;
  9. while(y){
  10. if(y& 1)ans=ans*x%mod;
  11. x=x*x%mod;
  12. y>>= 1;
  13. }
  14. return ans;
  15. }
  16. LL inv(LL x){
  17. return POW(x,mod -2);
  18. }
  19. LL a[N];
  20. void init(){ //预处理答案
  21. LL inv2=inv( 2);
  22. LL ans= 0,res= 1,sum=inv2;
  23. for( int i= 1;i
  24. res=res*( 1-sum+mod)%mod; //更新f
  25. sum=sum*inv2%mod; //更新分母
  26. ans^=res; //更新g
  27. a[i]=ans;
  28. }
  29. }
  30. int main()
  31. {
  32. init();
  33. int t; cin>>t;
  34. while(t--){
  35. int x; cin>>x;
  36. cout<endl;
  37. }
  38. system( "pause");
  39. return 0;
  40. }

C-Combination of Physics and Maths

  •  一列一列的去找,因为两列合并时\frac{a}{b}<=\frac{a+c}{b+d}<=\frac{c}{d},即合并之后的值处于两者之间不超过较大值,那么就没有合并的意义了,一列一列的更新最大值。
  • 因为分母是选取的子矩阵的最后一行,因此可以扩大分子,即从第一行开始加到子矩阵末尾。

   
   
   
   
  1. #include
  2. using namespace std;
  3. int a[ 205][ 205],b[ 205][ 205];
  4. int main(){
  5. int t;
  6. scanf( "%d",&t);
  7. for( int i= 0;i
  8. int n,m; double mx= -1;
  9. scanf( "%d%d",&n,&m);
  10. for( int i= 1;i<=n;i++){
  11. for( int j= 1;j<=m;j++){
  12. scanf( "%d",&a[i][j]);
  13. b[i][j]=b[i -1][j]+a[i][j]; //前缀和
  14. mx=max(mx,b[i][j]* 1.0/a[i][j]);
  15. }
  16. } printf( "%.8lf\n",mx);
  17. }
  18. return 0;
  19. }

 E-Easy Construction

  •  构造题。问1-n的排列是否能组成一个这样的序列,使得他同时存在长度为1-n的连续子序列,他们的和都满足sum%n=k%n
  • 首先长度为n的子序列只有一个(它本身),那么sum=n*(n+1)/2,如果k不满足sum%n==k%n的话,直接输出-1
  • n为奇数时,sum%n=0,那么就这么构造n,1,n-1,2,n-2...n/2,n/2+1
  • n为偶数时,sum%n=n/2,那么就这么构造n,n/2,1,n-1,2,n-2...n/2-1,n/2+1

   
   
   
   
  1. #include
  2. using namespace std;
  3. #define LL long long
  4. int main(){
  5. int n,k;
  6. cin>>n>>k;
  7. int sum=n*(n+ 1)/ 2;
  8. if(sum%n!=k%n) cout<< -1<< endl;
  9. else if(n& 1){
  10. cout<
  11. for( int i= 1;i<=n/ 2;i++) cout<< " "<" "<
  12. cout<< endl;
  13. } else{
  14. cout<" "<2;
  15. for( int i= 1;i2;i++) cout<< " "<" "<
  16. cout<< endl;
  17. }
  18. system( "pause");
  19. return 0;
  20. }

 G-Grid Coloring

  • 构造题。拿k种不同颜色 火柴拜访成n*n个正方形,必须满足:
  • 每种颜色的火柴花的数量相同
  • 一个正方形环上不能都是相同颜色的火柴
  • 每行每列火柴不能全部相同
  1. n=1和k=1的情况肯定摆不出
  2. 可以按照从左到右依次1 2 3 4 5...摆放
  3. 如果n是k的倍数的话,如果还是从左到右扫描的话,那么左上角的正方形四条边都会是同样的颜色,不满足条件,所以另起一行是++tmp
  4. 如果n不是k的倍数的话,那么不影响

   
   
   
   
  1. #include
  2. using namespace std;
  3. #define sc(a) scanf("%d",&a)
  4. int n,k;
  5. void color(){
  6. int tmp= 0;
  7. if(n%k){
  8. for( int i= 1;i<=(n+ 1)* 2;i++){
  9. for( int j= 1;j<=n;j++){
  10. tmp=tmp%k+ 1;
  11. cout<" ";
  12. }
  13. cout<< endl;
  14. }
  15. } else{
  16. for( int i= 1;i<=(n+ 1)* 2;i++){
  17. for( int j= 1;j<=n;j++){
  18. tmp=tmp%k+ 1;
  19. cout<" ";
  20. }tmp=tmp%k+ 1;
  21. cout<< endl;
  22. }
  23. }
  24. }
  25. int main(){
  26. int t;sc(t);
  27. for( int i= 0;i
  28. sc(n);sc(k);
  29. if(n== 1||k== 1|| 2*n*(n+ 1)%k) puts( "-1");
  30. else color();
  31. }
  32. return 0;
  33. }

 

你可能感兴趣的:(2020牛客多校(第六场))