『模拟赛』多校A层冲刺NOIP2024炼石计划23
Rank
懒得尝试
100 + 10 + 0 + 25 = 135pts,rk60
A. 排序
签。
比较好想的是按位找第一个相邻两数不同的二进制位,标记强制换/强制不换,每次求答案时扫一遍,如果矛盾输出 -1,否则计算强制换的位数的贡献之和输出。时间复杂度 \(\mathcal{O(n\log V)}\)。
点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
#define lx ll
inline lx qr()
{
char ch = getchar(); lx x = 0, f = 1;
for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);
return x * f;
}
#undef lx
#define qr qr()
#define pll pair<ll, ll>
#define pii pair<int, int>
#define ppp pair<pii, pii>
#define fi first
#define se second
#define M_P(x, y) make_pair(x, y)
#define P_B(x) push_back(x)
const int Ratio = 0;
const int N = 1e6 + 5;
const int mod = 1e9 + 7;
int n, q;
int a[N];
int must[30], no[30];
namespace Wisadel
{
inline int Wclac()
{
int res = 0;
fu(i, 29, 0)
{
if(must[i] && no[i]) return -1;
if(must[i]) res += (1 << i);
}
return res;
}
inline void Wupd(int x, int y, int v)
{
fu(i, 29, 0)
{
int z1 = (x >> i) & 1, z2 = (y >> i) & 1;
if(!(z1 ^ z2)) continue;
else if(z1) must[i] += v;
else if(z2) no[i] += v;
break;
}
}
short main()
{
freopen("sort.in", "r", stdin), freopen("sort.out", "w", stdout);
n = qr;
fo(i, 1, n) a[i] = qr;
fo(i, 1, n - 1) Wupd(a[i], a[i + 1], 1);
q = qr;
printf("%d\n", Wclac());
fo(i, 1, q)
{
int x = qr, k = qr;
if(x != 1) Wupd(a[x - 1], a[x], -1), Wupd(a[x - 1], k, 1);
if(x != n) Wupd(a[x], a[x + 1], -1), Wupd(k, a[x + 1], 1);
a[x] = k;
printf("%d\n", Wclac());
}
return Ratio;
}
}
signed main(){return Wisadel::main();}
// All talk and never answer
B. 交换
把序列看成排列,每轮操作可以理解成在序列上进行一次置换,置换是具有结合律的。
考虑当 \(n\ |\ m\) 时,每轮操作相同,由于置换具有结合律,我们可以用快速幂的方法求出执行完 \(\lfloor\frac{t}{n}\rfloor\) 轮操作后的排列,剩下暴力求解,复杂度 \((n+m)\log t\)。
考虑一般情况时,我们操作完一轮后下一次操作的 \(a\) 的下标中 \(+i\) 与第一次的 \(+i\) 可能不相等,那么就会导致下次操作的起始点不同,怎么办呢?我们直接将它循环左移一定的位数使得二者的起始点相同,那么之后就可以重复这样的操作了。我们设一轮 \(m\) 次的置换操作为 \(M\),循环左移的操作为 \(L\),右移的操作为 \(R\),那么整个过程可以写为 \(MLMLM\cdots MLMR^{\lfloor\frac{t}{n}\rfloor-1}\),将 \(ML\) 看成一整次操作,仍然可以用快速幂求解,最后余数仍然暴力处理,总时间复杂度仍然是 \(\mathcal{O((n+m)\log t)}\) 的。
点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
#define lx ll
inline lx qr()
{
char ch = getchar(); lx x = 0, f = 1;
for(; ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);
return x * f;
}
#undef lx
#define qr qr()
#define pll pair<ll, ll>
#define pii pair<int, int>
#define ppp pair<pii, pii>
#define fi first
#define se second
#define M_P(x, y) make_pair(x, y)
#define P_B(x) push_back(x)
const int Ratio = 0;
const int N = 1e5 + 5;
const int mod = 998244353;
ll n, m, t;
int a[N], b[N], c[N];
struct rmm
{
int a[N];
rmm operator * (rmm A) const
{
rmm ZC;
fo(i, 0, n - 1) ZC.a[i] = a[A.a[i]];
return ZC;
}
} M, ans, L, R;
namespace Wisadel
{
inline rmm Wqp(rmm x, ll y)
{
rmm res;
fo(i, 0, n - 1) res.a[i] = i;
while(y){if(y & 1) res = res * x; x = x * x; y >>= 1;}
return res;
}
short main()
{
freopen("swap.in", "r", stdin), freopen("swap.out", "w", stdout);
n = qr, m = qr, t = qr;
fo(i, 0, n - 1) a[i] = qr, M.a[i] = ans.a[i] = i;
fo(i, 0, m - 1) b[i] = qr, c[i] = qr;
fo(i, 1, m) swap(M.a[(b[i % m] + i) % n], M.a[(c[i % m] + i) % n]);
fo(i, 0, n - 1) L.a[i] = (i + m) % n, R.a[i] = (i - m % n + n) % n;
ll zc = t / m;
if(zc > 0) ans = ans * M, M = L * M, ans = ans * Wqp(M, zc - 1), ans = ans * Wqp(R, zc - 1);
t %= m;
fo(i, 1, t) swap(ans.a[(b[i] + i + zc * m) % n], ans.a[(c[i] + i + zc * m) % n]);
fo(i, 0, n - 1) printf("%d ", a[ans.a[i]]);
return Ratio;
}
}
signed main(){return Wisadel::main();}
// All talk and never answer
C. 计算
正解是 dp + 拉插。
D. 莫队
将答案分为散块(未被推平过)和整块计算,都可以通过离线扫描线求解。
末
萌熊常规饭堂。
切了 T1 之后就有点摆了,T2 静不下心推性质,只拿了最低档分,T3 猜假了第一档,T4 也就暴力。
状态有点离线不知道为啥。
下午体活打球再次被重击,这次好像是镜片,被压了之后直接划了一道,别样的还不让洗澡(
晚上还有 arc,可能真是在役最后一场了,所以改题先咕咕,切打且珍惜。