B.Binary Vector
题意:
设A={0,1},每天Roundgod从{A^n}(即维度为n,每一位由01组成的所有向量的集合)中随机选择一个二进制向量。现在他想知道n天中选取n个线性独立向量的概率在mod1e9 + 7 下的值。
其实也可以根据题目下面给出的提示去猜出公式,但是这里的数据实在太大,所以我要打表。
已经知道1/2 %mod == 5e8 + 4,
我们推出f(n) = f(n-1)*(2n - 1) / (2n)
根据此公式推出:
分母的公式为2 1 + 22 + 23 + … 2n
整理得: 2n*(n+1)/2
分子为:21-1 * 22-1 * 23-1…2n-1
又由费马小定理: 1/2 %mod == 2(mod-2)
那么同理1/4 == 1/2 * 1/2 ,所以 1/4 %mod == 2(mod-2) * 2(mod-2)
所以我们可以推到1/2n的逆元上,那么就可以省很多时间
加粗的就是重点理解的地方
AC代码
#include
inline long long read(){char c = getchar();long long x = 0,s = 1;
while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();}
return x*s;}
using namespace std;
#define NewNode (TreeNode *)malloc(sizeof(TreeNode))
#define Mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x)&(-x)
const int N = 2e7 + 5;
const long long INFINF = 0x7f7f7f7f7f7f7f;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-7;
const int mod = 1e9 + 7;
const double II = acos(-1);
const double PP = (II*1.0)/(180.00);
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> piil;
ll arr[N];
ll quick_pow(ll a,ll b)
{
ll ans = 1;
while(b)
{
if(b&1)
ans = a*ans%mod;
b>>=1;
a = a*a%mod;
}
return ans;
}
void solve()
{
arr[1] = 5e8 + 4;//1/2%mod的结果
ll b = 2,Inv = arr[1];//b代表的是现在的分母增量,Inv是分母逆元的增量
for(int i = 2;i <= N;i++)
{
b = b *2 % mod;
Inv = Inv * arr[1] % mod;
arr[i] = arr[i-1]*(b-1+mod)%mod*Inv%mod;
//(b-1+mod)%mod为分子增量,Inv为分母增量,而arr[i-1]为前一个数的值,
}
for(int i = 2;i <= N;i++)
arr[i] ^= arr[i-1];
}
signed main()
{
std::ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
solve();
ll t;
t = read();
while(t--)
{
ll n;
n = read();
printf("%lld\n",arr[n]);
}
}
C.Combination of Physics and Maths
这里有一个数学原理:
a/b <= a + c / b + d <= c/d
所以,我们选的时候,可以是选一列即可,而在面积S相同的情况下,肯定是分子F越大越好,所以直接枚举即可
AC代码
#include
inline long long read(){char c = getchar();long long x = 0,s = 1;
while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();}
return x*s;}
using namespace std;
#define NewNode (TreeNode *)malloc(sizeof(TreeNode))
#define Mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x)&(-x)
const int N = 2e6 + 5;
const long long INFINF = 0x7f7f7f7f7f7f7f;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-7;
const int mod = 998244353;
const double II = acos(-1);
const double PP = (II*1.0)/(180.00);
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> piil;
signed main()
{
std::ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
int t;
cin >> t;
while(t--)
{
int n,m;
cin >> n >> m;
int arr[n+5][m+5];
double Max = 0.000000;
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++)
cin >> arr[i][j];
for(int i = 1;i <= m;i++)
{
int sum = 0;
for(int j = 1;j <= n;j++)
{
sum += arr[j][i];
Max = max(Max,(sum*1.00)/(arr[j][i]));
}
}
cout << fixed << setprecision(8) << Max << endl;
}
}
E.Easy Construction
有求和公式:
n*(n+1)/2
既然是每一个长度都有,我们何不从长度为n入手呢?(长度为n的只有一个)
所以有情况:
1.当n为偶数时,n*(n+1)/2 % n == n/2,所以k一定等于n/2,然后再按一定方法构造即可
2.当n为奇数时,n*(n+1)/2%n == 0,所以k一定等于0
AC代码
#include
inline long long read(){char c = getchar();long long x = 0,s = 1;
while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();}
return x*s;}
using namespace std;
#define NewNode (TreeNode *)malloc(sizeof(TreeNode))
#define Mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x)&(-x)
const int N = 2e6 + 5;
const long long INFINF = 0x7f7f7f7f7f7f7f;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-7;
const int mod = 998244353;
const double II = acos(-1);
const double PP = (II*1.0)/(180.00);
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> piil;
signed main()
{
std::ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
int n,k;
cin >> n >> k;
if(n % 2 != 0 && k == 0)
{
cout << n << " ";
for(int i = 1;i <= n/2;i++)
cout << i << " " << n-i << " ";
cout << endl;
}
else if(n % 2 == 0 && k == n/2)
{
cout << n << " " << n/2 << " ";
for(int i = 1;i < n/2;i++)
cout << i << " " << n - i << " ";
cout << endl;
}
else
cout << -1 << endl;
}
K. K-Bag
思路;
因为数据太大,所以离散化一下,然后从前面的端点开始枚举,枚举后面的是否满足条件
AC代码
#include
inline long long read(){char c = getchar();long long x = 0,s = 1;
while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();}
return x*s;}
using namespace std;
#define NewNode (TreeNode *)malloc(sizeof(TreeNode))
#define Mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x)&(-x)
const int N = 5e5 + 5;
const long long INFINF = 0x7f7f7f7f7f7f7f;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-7;
const int mod = 1e9 + 7;
const double II = acos(-1);
const double PP = (II*1.0)/(180.00);
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> piil;
int len[N],a[N],b[N],vis[N];
signed main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
int t;
cin >> t;
while(t--)
{
int n,k,aa = 1;
cin >> n >> k;
for(int i = 1;i <= n;i++)
{
cin >> a[i];
b[i] = a[i];
if(a[i] > k || a[i] <= 0)
aa = 0;
}
if(!aa) {cout << "NO" << endl;continue;}
sort(b+1,b+n+1);
int lenb = unique(b+1,b+1+n)-b-1,ans = 1,flag = 0;
for(int i = 1;i <= n;i++)
a[i] = lower_bound(b+1,b+lenb+1,a[i])-b;
for(int i = 1;i <= n;i++)
{
while(!vis[a[ans]] && ans <= n)
{
vis[a[ans]]++;
ans++;
}
vis[a[i]]--;
len[i] = ans-i;
// cout << ans << " " << i << " " << len[i] << endl;
}
for(int i = 1;i <= min(k,len[1]+1);i++)
{
int q = 1;
for(int j = i;j <= n;j += k)
{
if(j + len[j] > n) continue;
else if(len[j] != k) {q = 0;break;}
}
if(q) {flag = 1;break;}
}
if(flag) cout << "YES" << endl;
else cout << "NO" << endl;
}
}