11.22 模拟赛
A.#
将原式进一步化简可得
时间复杂度:
哎赛事代码太丑了点。
代码
#includetypedef unsigned long long ull;
const int N = 1e6 + 7;
int a[N], b[N];
int aa[N], bb[N], cc[N], c[N];
bool op[N];
int x[N], v[N];
int T1[N], T2[N], T3[N];
int n, q, V;
int lowbit(int x) {return x & (-x);}
int query1(int pos) {
int res = 0;
for(int i = pos; i; i -= lowbit(i)) res += T1[i];
return res;
}
void modify1(int pos, int x) {
for(int i = pos; i <= n; i += lowbit(i)) T1[i] += x;
}
int getsum1(int l, int r) {
if(r < l) return 0;
return query1(r) - query1(l - 1);
}
int query2(int pos) {
int res = 0;
for(int i = pos; i; i -= lowbit(i)) res += T2[i];
return res;
}
void modify2(int pos, int x) {
for(int i = pos; i <= n; i += lowbit(i)) T2[i] += x;
}
int getsum2(int l, int r) {
if(r < l) return 0;
return query2(r) - query2(l - 1);
}
int query3(int pos) {
int res = 0;
for(int i = pos; i; i -= lowbit(i)) res += T3[i];
return res;
}
void modify3(int pos, int x) {
for(int i = pos; i <= n; i += lowbit(i)) T3[i] += x;
}
int getsum3(int l, int r) {
if(r < l) return 0;
return query3(r) - query3(l - 1);
}
void gen(int n,int q,int V,ull seed){
std::mt19937_64 rnd(seed);
for(int i = 1; i <= n; i ++) a[i] = rnd() % (V + 1);
for(int i = 1; i <= n; i ++) b[i] = rnd() % (V + 1);
for(int i = 1; i <= q; i ++) op[i] = rnd() & 1, x[i] = rnd() % n + 1, v[i] = rnd() % (V + 1);
}
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9')
x=x*10+ch-'0',ch=getchar();
return x*f;
}
void write(int x)
{
if(x<0)
putchar('-'),x=-x;
if(x>9)
write(x/10);
putchar(x%10+'0');
return;
}
signed main() {
freopen("calculate.in", "r", stdin);
freopen("calculate.out", "w", stdout);
ull seed;
n = read(), q = read(), V = read(), seed = read();
gen(n, q, V, seed);
// int n;
// cin >> n;
// for(int i = 1; i <= n; i ++) cin >> a[i];
// for(int i = 1; i <= n; i ++) cin >> b[i];
for(int i = 1; i <= n; i ++) {
modify1(i, a[i]);
modify2(i, b[i]);
modify3(i, a[i] * b[i]);
}
// cout << t1.query(n);
// for(int i = 1; i <= n; i ++) cout << a[i] << " ";
// cout << endl;
// for(int i = 1; i <= n; i ++) cout << b[i] << " ";
// cout << endl;
// int ans = 0;
// for(int i = 1; i <= n - 1; i ++) for(int j = i + 1; j <= n; j ++) ans += (a[i] - a[j]) * (b[i] - b[j]);
// cout << ans << endl;
int ans1 = 0, ans2 = 0;
for(int i = 1; i <= n; i ++) ans1 += (n - i) * a[i] * b[i];
for(int i = 1; i <= n; i ++) ans1 -= (a[i] * getsum2(i + 1, n) + b[i] * getsum1(i + 1, n) - getsum3(i + 1, n));
write(ans1);
puts("");
for(int i = 1; i <= q; i ++) {
if(op[i] == 0) {
ans1 -= (n - x[i]) * a[x[i]] * b[x[i]];
ans1 += (n - x[i]) * v[i] * b[x[i]];
int p = v[i] - a[x[i]];
int now = getsum2(1, x[i] - 1) * p;
ans1 -= now;
int p2 = v[i] * b[x[i]] - a[x[i]] * b[x[i]];
ans1 += (x[i] - 1) * p2;
ans1 -= getsum2(x[i] + 1, n) * p;
write(ans1);
puts("");
modify1(x[i], -a[x[i]]);
modify1(x[i], v[i]);
a[x[i]] = v[i];
}
else {
ans1 -= (n - x[i]) * a[x[i]] * b[x[i]];
ans1 += (n - x[i]) * v[i] * a[x[i]];
int p = v[i] - b[x[i]];
int now = getsum1(1, x[i] - 1) * p;
ans1 -= now;
int p2 = v[i] * a[x[i]] - a[x[i]] * b[x[i]];
ans1 += (x[i] - 1) * p2;
ans1 -= getsum1(x[i] + 1, n) * p;
write(ans1);
puts("");
modify2(x[i], -b[x[i]]);
modify2(x[i], v[i]);
b[x[i]] = v[i];
}
}
}
从小到大往里填数,
假设把第
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 7;
int dp[201][201][1026];
int vis[201][201][1026];
int get(int s, int x) {
int cnt = 0;
while(s) {
if(s % 2 == x) cnt ++;
s >>= 1;
}
return cnt;
}
int n, k, mod;
int C[202][202];
void sol1() {
for(int i = 0; i <= 2 * n; i ++) C[i][i] = C[i][0] = 1;
for(int i = 1; i <= 2 * n; i ++) {
for(int j = 1; j < i; j ++) {
C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
}
}
cout << C[2 * n][n] % mod;
}
signed main() {
// 10000
cin >> n >> k >> mod;
if(k == 1) {
sol1();
return 0;
}
k --;
int ss = (1 << k) - 1;
dp[0][1][1] = 1;
dp[1][0][0] = 1;
for(int i = 0; i <= n; i ++) {
for(int j = 0; j <= n; j ++) {
int cnt = 0;
for(int s = 0; s < (1 << k); s ++) {
if(vis[i][j][s]) continue;
// vis[i][j][s] = 1;
int len = min(i + j, k);
int sm1 = get(s, 1);
int sm0 = len - sm1;
// cout << "from: " << i << " " << j << " " << s << " " << sm0 << " " << sm1 << " " << dp[i][j][s] << endl;
if(i > j) {
dp[i + 1][j][(s << 1) & ss] = (dp[i + 1][j][(s << 1) & ss] + dp[i][j][s]) % mod;
// cout << i + 1 << " " << j << " " << ((s << 1) & ss) << " " << dp[i + 1][j][(s << 1) & ss] << "\n";
if(sm0 >= i - j) continue;
dp[i][j + 1][((s << 1) & ss) | 1] = (dp[i][j + 1][((s << 1) & ss) | 1] + dp[i][j][s]) % mod;
// cout << i << " " << j + 1 << " " << ((s << 1) & ss | 1) << " " << dp[i][j + 1][(s << 1) & ss | 1] << "\n";
}
else if(j > i) {
dp[i][j + 1][((s << 1) & ss) | 1] = (dp[i][j + 1][((s << 1) & ss) | 1] + dp[i][j][s]) % mod;
// cout << i << " " << j + 1 << " " << ((s << 1) & ss | 1) << " " << dp[i][j + 1][(s << 1) & ss | 1] << "\n";
if(sm1 >= j - i) continue;
dp[i + 1][j][(s << 1) & ss] = (dp[i + 1][j][(s << 1) & ss] + dp[i][j][s]) % mod;
// cout << i + 1 << " " << j << " " << ((s << 1) & ss) << " " << dp[i + 1][j][(s << 1) & ss] << "\n";
}
else {
dp[i][j + 1][((s << 1) & ss) | 1] = (dp[i][j + 1][((s << 1) & ss) | 1] + dp[i][j][s]) % mod;
// cout << i + 1 << " " << j << " " << ((s << 1) & ss) << " " << dp[i + 1][j][(s << 1) & ss] << "\n";
dp[i + 1][j][(s << 1) & ss] = (dp[i + 1][j][(s << 1) & ss] + dp[i][j][s]) % mod;
// cout << i << " " << j + 1 << " " << ((s << 1) & ss | 1) << " " << dp[i][j + 1][(s << 1) & ss | 1] << "\n";
}
}
}
}
int ans = 0;
for(int i = 0; i < (1 << k); i ++) ans = (ans + dp[n][n][i]) % mod;
cout << ans << endl;
}
//
C.#
考虑到不能连续走
但是有一个问题是如果把边看成点跑最短路,那么边到边之间的转移可能会有
但是考虑到整张图是不带权的,只要
现在考虑如何删除
D.#
50pts#
发现在序列中比较好做,
考虑把它放树上,在 dfs 的过程中统计答案即可,从根开始,进入子树时统计贡献,出子树的时候把贡献撤销即可。
时间复杂度
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!