2020牛客暑期多校六
6B-Binary Vector(线性独立,逆元)
#include <bits/stdc++.h> using namespace std; #define ll long long using namespace std; const int mod = 1e9+7;/// 998244353; const int mxn = 2e7 +7; ll _,m,n,t,k,ans; ll a[mxn] ; void solve() { ll x = 0 , y = 1 , inv = 5e8+4 ; a[0] = 1 ; for(int i=1;i<=mxn;i++){ x = (x*2 + 1) % mod ; y = y*inv % mod ; a[i] = a[i-1] * x % mod * y % mod ; } for(int i=2;i<=mxn;i++) a[i]^=a[i-1]; for(cin>>t;t;t--) { cin>>n; cout<<a[n]<<endl; } } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); solve(); }
6C-Combination of Physics and M
#include <bits/stdc++.h> using namespace std; #define ll long long using namespace std; const int mod = 1e8;/// 998244353; const int mxn = 3e2 +7; ll _,m,n,t,k,ans; int dp[mxn] , a[mxn][mxn]; void solve() { for(cin>>t;t;t--) { cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>a[i][j]; memset(dp,0,sizeof(dp)); double ans = 0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) ans = max(ans, (dp[j]+=a[i][j])/(double)a[i][j] ); } cout<<fixed<<setprecision(10)<<ans<<endl; } } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); solve(); }
6E-Easy Construction
:构造一个长度为N序列P,使的序列 P 存在长度为 [ 1 , N ]的子序列的和 S mod N = K ,也就是构造出一个存在 N 个不同长度的子序列X,且X的和 S mod N = K
:可以使用求和公式(1+n)* n / 2 判断是否满足存在 N 个数的和 S mod N = K ,
S mod N != K ,-1
S mod N = K 时 ,由双数组成的和为N的个数为(N-1)/2个,加上本身个数1个,那么总个数记为 ans = (N-1)/ 2 + 1 个
N&1 = 1 :能够满足 N 个不同长度的子序列X,且X的和 S mod N = K 的K值只能是0 ,因为[1,N]被用于组成N中,那么序列可以是【1 , N-1 , 2 , N-2 , 3 , N-3 ... N 】
N&1 = 0 :能够满足 N 个不同长度的子序列X,且X的和 S mod N = K 的K值只能是N/2,因为其他数被用于组成N中,那么序列可以是【N , N/2 , 1 , N-1 , 2 , N-2 ....】
又说,为什么不能是K=0呢?是因为如果K=0,那么长度为N的序列就不满足序列和 S mod N =0
#include <bits/stdc++.h> using namespace std; #define ll long long using namespace std; const int mod = 1e8;/// 998244353; const int mxn = 15 +7; ll _,m,n,t,k,ans; int dp[mxn][1<<13] , a[mxn][mxn] , f[mxn] , sta[1<<13] ; void solve() { while(cin>>n>>m){ ans = (1+n)*n/(2*1ll); if(ans%n==m){ if(n&1){ if(m==0){ cout<<n<<' '; for(int i=1;i<=n/2;i++) cout<<i<<" "<<n-i<<(i==n/2?'\n':' '); } else { cout<<-1; } } else { if(m==n/2){ cout<<n<<' '<<n/2<<' '; for(int i=1;i<n/2;i++) cout<<i<<" "<<n-i<<(i==n/2-1?'\n':' '); } else { cout<<-1; } } } else { cout<<-1; } cout<<endl; } } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); solve(); }
6K-K-Bag
:其实这个k-bag可以理解为【k个数做全排列,然后选出【M个全排列】组成一个数字串】
:然后问题的实质就是问给定的序列是不是数字串的一个子串
:因为K范围很大,全排列情况很多,不可能一一对比,那么也就是可以简化为给定的序列是否满足以下的情况:
【Bag + --- +Bag 】,【y*part-Bag(0<=y<=1) + m*Bag(M>=0) +x*part-Bag (0<=x<=1) 】
part-Bag是指K个数做全排列后的一部分
#include <bits/stdc++.h> using namespace std; #define ll long long using namespace std; const int mod = 1e9+7;/// 998244353; const int mxn = 1e6 +7; int _,m,n,t,k,ans,tep; int a[mxn] , b[mxn] , pre[mxn] , len[mxn] ; void calc() { int ok = 0 ; for(int i=1;i<=min(k,len[1]+1);i++)/// min 过滤掉前面的一段字符是part-bag的情况 { for(int j=i;j<=n;j+=k) { if(j+len[j]-1==n) {/// 这里-1是因为len已经包含第j点,再加上j的话,多计算第j点一次,所以要减一 ok = 1 ; /// 这里成立的条件是最后的某段区间一定是Bag + (part-bag/Bag) break; } else if(len[j]^k) /// 会过滤掉 Bag(空字符串) + part-Bag + part-Bag + Bag(空字符串) break; } if(ok) break; } cout<<(ok?"YES":"NO")<<endl; } void solve() { for(cin>>t;t;t--) { cin>>n>>k; int ok = 0 ; for(int i=1;i<=n;i++){ cin>>a[i] , b[i] = a[i] ; if(a[i]>k) ok=1; } if(ok){ cout<<"NO"<<endl; continue; } sort(b+1,b+1+n); int cnt = unique(b+1,b+1+n) - b - 1 ; for(int i=1;i<=n;i++) a[i] = lower_bound(b+1,b+1+cnt,a[i]) - b ; /// 离散化,防止越界 int p = 1 ; for(int i=1;i<=n;i++) { while(p<=n && !pre[ a[p] ]) pre[ a[p] ]++ , p++ ;///一个BAG一定不含两个相同的数,所以 !pre[ a[p] ] pre[ a[i] ]-- , len[i] = p-i ;/// len记录以i为起点,part-bag or bag 的长度,也就是不包含重复数字的区间长度 } calc(); } } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); solve(); } /* 10 7 4 1 2 4 3 1 2 4 7 4 1 2 3 4 1 1 2 7 4 1 2 3 4 1 2 3 7 4 3 4 1 1 4 2 3 7 4 1 1 4 3 2 1 2 */
6G-Grid Coloring (构造)
#include <bits/stdc++.h> using namespace std; #define ll long long using namespace std; const int mod = 1e9+7;/// 998244353; const int mxn = 2e7 +7; ll _,m,n,t,k,ans; void solve() { for(cin>>t;t;t--) { cin>>n>>k; if(2*n*(n+1)%k!=0 || k==1 || n==1){ cout<<-1<<endl; continue; } if(n%k!=0) { ans = 1 ; for(int i=1;i<=2*n+2;i++){ for(int j=1;j<=n;j++){ cout<<ans<<(j==n?'\n':' '); ans%=k; ans++; /// 防止出现零 } } } else { ll col = 1 ; for(int i=1;i<=2*n+2;i++){ for(int j=1;j<=n;j++){ cout<<( (col+j-1)%k+1 )<<(j==n?'\n':' '); } col++; col%=k; } } } } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); solve(); }