比赛入口
E 做计数
做法:平方数的因子和
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
int main() {
LL n; read(n);
LL res = 0;
for(LL i = 1; i * i <= n; ++i) {
LL mid = i * i, j;
for(j = 1; j * j < mid; ++j)
if(mid % j == 0) {
++res;
if(mid / j != j) ++res;
}
++res;
}
cout << res << endl;
return 0;
}
F 拿物品
做法:要使得两人差值尽可能大,是两个属性的和进行排序
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int N = 2e5+5;
struct xx {
LL a, b;
int id;
bool operator < (const xx &c) const {
return a + b > c.a + c.b;
}
}obj[N];
int main() {
int n; read(n);
for(int i = 1; i <= n; ++i) { read(obj[i].a); obj[i].id = i; }
for(int i = 1; i <= n; ++i) read(obj[i].b);
sort(obj+1, obj+n+1);
for(int i = 1; i <= n; i += 2) printf("%d ", obj[i].id);
puts("");
for(int i = 2; i <= n; i += 2) printf("%d ", obj[i].id);
return 0;
}
C 算概率
做法:这题在比赛的时候想了好久啊,其实就是一个递推方程…
d
p
[
i
]
[
j
]
=
d
p
[
i
−
1
]
[
j
]
∗
(
1
−
p
[
i
]
)
+
d
p
[
i
−
1
]
[
j
−
1
]
∗
p
[
i
]
dp[i][j] = dp[i-1][j]*(1-p[i])+dp[i-1][j-1]*p[i]
dp[i][j]=dp[i−1][j]∗(1−p[i])+dp[i−1][j−1]∗p[i]
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示前
i
i
i个题目做对了
j
j
j道。
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int Mod = 1e9+7;
const int N = 2003;
LL dp[N][N], p[N];
int main() {
int n; read(n);
for(int i = 1; i <= n; ++i) read(p[i]);
dp[1][1] = p[1]; dp[1][0] = (1 - p[1] + Mod) % Mod;
for(int i = 2; i <= n; ++i) {
for(int j = 0; j <= i; ++j) {
dp[i][j] = (dp[i-1][j] * (1 - p[i] + Mod) % Mod + dp[i-1][j-1] * p[i] % Mod) % Mod;
}
}
for(int i = 0; i <= n; ++i) cout << dp[n][i] << " ";
cout << endl;
return 0;
}
H 施魔法
做法:简单的01背包…排过序后就是选当前的点或者不选当前的点…
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int N = 3e5+5;
LL a[N], dp[N];
int main() {
int n, k;
read(n); read(k);
for(int i = 1; i <= n; ++i) read(a[i]);
sort(a+1, a+n+1);
for(int i = 1; i <= n; ++i) dp[i] = 1e17;
for(int i = k; i <= n; ++i)
dp[i] = min(dp[i-k] + a[i] - a[i-k+1], dp[i-1] + a[i] - a[i-1]);
printf("%lld\n", dp[n]);
return 0;
}
I 建通道
做法:要找到最小的二进制位k,使得 a i a_i ai这个二进制位是0, a j a_j aj这个二进制位是1,答案是(去重后点数-1)*2^k
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
set<int> st;
int main() {
int n; read(n);
int x = 0, y = 0x7fffffff;
int a;
for(int i = 1; i <= n; ++i) {
read(a);
x |= a; y &= a;
st.insert(a);
}
x = x ^ y; x = x & (-x);
cout << (st.size()-1)*x;
return 0;
}
J 求函数
做法:貌似是函数化简+两颗线段树维护?