水题 看奇数个数是否为n
代码
#include
using namespace std;
int n, sum;
void solve()
{
cin >> n; sum = 0;
for (int i = 1; i <= n * 2; i ++ )
{
int a; cin >> a;
if (a & 1) sum ++ ;
}
if (sum == n) puts("YES");
else puts("NO");
}
int main()
{
int t;
cin >> t;
while (t -- )
{
solve();
}
return 0;
}
给定一个a和一个b 对于一个一定包含1的集合 (假如x在这个集合 那么 x * a 和 x + b 也一定在这个集合中) 给定一个n 问n是否在此集合中
我们可以将在集合中的数变为 a x a^x ax + y * b 所以遍历i直到 a i a^i ai大于n 每次看看是否可以%b==0 如果可以就yes
代码
#include
using namespace std;
typedef long long ll;
void solve()
{
ll n, a, b;
cin >> n >> a >> b;
if (a == 1 || b == 1)
{
if ((n - 1) % b) puts("NO");
else puts("YES");
return;
}
ll res = 1;
while (res <= n)
{
if ((n - res) % b == 0)
{
puts("YES");
return;
}
res *= a;
}
puts("NO");
}
int main()
{
int t;
cin >> t;
while (t -- )
{
solve();
}
return 0;
}
用 f(i) 表示最小的x i 无法被 x 整除 给定一个n 求 f(1) + … + f(n) 的sum值
我们可以这样想 lcm( a 1 , a 2 , . . . , a n a_{1}, a_{2}, ... ,a_{n} a1,a2,...,an) 是可以分别被 a 1 , a 2 , . . . , a n a_{1}, a_{2}, ..., a_{n} a1,a2,...,an整除的 我们可以i从小到大遍历 求1~i 的lcm 看看n中有多少数字能整除此时的lcm 即这些可以整除的数要往后推一位 初始化所有 f(i) 为1
代码
#include
using namespace std;
typedef long long ll;
const ll P = 1e9 + 7;
ll gcd(ll a, ll b)
{
return b ? gcd(b, a % b) : a;
}
ll lcm(ll a, ll b)
{
return a / gcd(a, b) * b;
}
void solve()
{
ll n; cin >> n;
ll ans = n, lc = 1;
for (int i = 2; lc <= n; i ++ )
{
(ans += (n / lc)) %= P;
lc = lcm(lc, i);
}
cout << ans << endl;
}
int main()
{
int t;
cin >> t;
while (t -- )
{
solve();
}
return 0;
}
一个计数dp 还挺难思考的 我们用 d p i , j dp_{i,j} dpi,j表示从1到 i 中有 j 个数小于 a k a_{k} ak 这样的方案数
因为n不大 所以我们可以直接遍历 这样的时间复杂度为 O( n 3 n^{3} n3) 这样分类来看 我们可以把所有的 - 都看为 a i a_{i} ai = -1
对于每一个 d p i , j dp_{i,j} dpi,j都是从 d p i − 1 , j dp_{i-1,j} dpi−1,j转移过来的 (即当前集合不选择 a i a_{i} ai)
当 a i a_{i} ai = -1的时候 我们选择拿这个 就有了 d p i , j dp_{i,j} dpi,j += d p i − 1 , j + 1 dp_{i-1,j+1} dpi−1,j+1 以及 += d p i − 1 , j dp_{i-1,j} dpi−1,j 后者是在 j = 0 的时候才加的一种方案 弹出一个大的数依然是 d p i − 1 , j dp_{i-1,j} dpi−1,j
如果 a i a_{i} ai != -1 我们可以通过比大小
如果 a i a_{i} ai > a k a_{k} ak || a i a_{i} ai= a k a_{k} ak && i > k 则 d p i , j dp_{i,j} dpi,j += d p i − 1 , j dp_{i-1,j} dpi−1,j
如果 a i a_{i} ai < a k a_{k} ak || a i a_{i} ai= a k a_{k} ak && i < k 则 d p i , j dp_{i,j} dpi,j += d p i − 1 , j − 1 dp_{i-1,j-1} dpi−1,j−1
每次维护一下ans即可
代码
#include
using namespace std;
typedef long long ll;
const int N = 510, P = 998244353;
int n;
ll dp[N][N], a[N], ans;
void solve()
{
cin >> n;
for (int i = 1; i <= n; i ++ )
{
char c; cin >> c;
if (c == '-') a[i] = -1;
else cin >> a[i];
}
for (int i = 1; i <= n; i ++ )
{
if (a[i] == -1) continue;
memset(dp, 0, sizeof dp);
dp[0][0] = 1;
for (int j = 1; j <= n; j ++ )
for (int k = 0; k <= j; k ++ )
{
(dp[j][k] += dp[j - 1][k]) %= P;
if (a[j] == -1)
{
(dp[j][k] += dp[j - 1][k + 1]) %= P;
if (k == 0 && j < i) (dp[j][k] += dp[j - 1][k]) %= P;
}
else
{
if (i == j) continue;
if (a[j] < a[i] || a[j] == a[i] && j < i)
{
if (k != 0)
(dp[j][k] += dp[j - 1][k - 1]) %= P;
}
else (dp[j][k] += dp[j - 1][k]) %= P;
}
}
for (int j = 0; j <= n; j ++ )
(ans += dp[n][j] * a[i]) %= P;
}
cout << ans << endl;
}
int main()
{
cin.tie(0);
ios::sync_with_stdio(false);
solve();
return 0;
}