天天看点

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

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

 B-Binary Vector

  • 看样例可得
    2020牛客多校(第六场)2020牛客暑期多校训练营(第六场)解题报告
    ,
  • 答案
    2020牛客多校(第六场)2020牛客暑期多校训练营(第六场)解题报告
    ,只需要求一次2的逆元就够了
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;
  4. const int mod = + ;
  5. const int N = + ;
  6. LL POW(LL x,LL y)
  7. {
  8. LL ans= ;
  9. while(y){
  10. if(y& )ans=ans*x%mod;
  11. x=x*x%mod;
  12. y>>= ;
  13. }
  14. return ans;
  15. }
  16. LL inv(LL x){
  17. return POW(x,mod );
  18. }
  19. LL a[N];
  20. void init(){ //预处理答案
  21. LL inv2=inv( );
  22. LL ans= ,res= ,sum=inv2;
  23. for( int i= ;i<N;i++){
  24. res=res*( -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<<a[x]<< endl;
  37. }
  38. system( "pause");
  39. return ;
  40. }

C-Combination of Physics and Maths

  •  一列一列的去找,因为两列合并时
    2020牛客多校(第六场)2020牛客暑期多校训练营(第六场)解题报告
    ,即合并之后的值处于两者之间不超过较大值,那么就没有合并的意义了,一列一列的更新最大值。
  • 因为分母是选取的子矩阵的最后一行,因此可以扩大分子,即从第一行开始加到子矩阵末尾。
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int a[ ][ ],b[ ][ ];
  4. int main(){
  5. int t;
  6. scanf( "%d",&t);
  7. for( int i= ;i<t;i++){
  8. int n,m; double mx= ;
  9. scanf( "%d%d",&n,&m);
  10. for( int i= ;i<=n;i++){
  11. for( int j= ;j<=m;j++){
  12. scanf( "%d",&a[i][j]);
  13. b[i][j]=b[i ][j]+a[i][j]; //前缀和
  14. mx=max(mx,b[i][j]* /a[i][j]);
  15. }
  16. } printf( "%.8lf\n",mx);
  17. }
  18. return ;
  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<bits/stdc++.h>
  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+ )/ ;
  8. if(sum%n!=k%n) cout<< << endl;
  9. else if(n& ){
  10. cout<<n;
  11. for( int i= ;i<=n/ ;i++) cout<< " "<<i<< " "<<n-i;
  12. cout<< endl;
  13. } else{
  14. cout<<n<< " "<<n/ ;
  15. for( int i= ;i<n/ ;i++) cout<< " "<<i<< " "<<n-i;
  16. cout<< endl;
  17. }
  18. system( "pause");
  19. return ;
  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<bits/stdc++.h>
  2. using namespace std;
  3. #define sc(a) scanf("%d",&a)
  4. int n,k;
  5. void color(){
  6. int tmp= ;
  7. if(n%k){
  8. for( int i= ;i<=(n+ )* ;i++){
  9. for( int j= ;j<=n;j++){
  10. tmp=tmp%k+ ;
  11. cout<<tmp<< " ";
  12. }
  13. cout<< endl;
  14. }
  15. } else{
  16. for( int i= ;i<=(n+ )* ;i++){
  17. for( int j= ;j<=n;j++){
  18. tmp=tmp%k+ ;
  19. cout<<tmp<< " ";
  20. }tmp=tmp%k+ ;
  21. cout<< endl;
  22. }
  23. }
  24. }
  25. int main(){
  26. int t;sc(t);
  27. for( int i= ;i<t;i++){
  28. sc(n);sc(k);
  29. if(n== ||k== || *n*(n+ )%k) puts( "-1");
  30. else color();
  31. }
  32. return ;
  33. }