基本信息
本赛季由 jr-zlw \texttt{\color{#AA00AA}{jr-zlw}} jr-zlw, Skyzhou \texttt{\color{#03A89E} Skyzhou} Skyzhou 和 sunchaoyi \texttt{\color{#0000FF}sunchaoyi} sunchaoyi 组队,全靠大佬带飞~。
中文队名:正在验证该队是否是真人。这可能需要五小时时间。
英文队名:Verifying we are human. This may take five hours.
训练记录
2025.05.02 The 2023 Guangdong Provincial Collegiate Programming Contest
备战省赛,也是组队后的第一次训练。
这一场签到题比较多,一小时以内按顺序过了 A,I,C,D,K。接下来我和 Sky 讨论了一下 M 的做法,确定了 O ( n 2 ) O(n^2) O(n2) 的 DP 维护直径,其间 Zlw 一眼 B 板子题,在 1.5h 一发通过了该题。
之后我和 Zlw 尝试口胡 E,F,没错他基本口胡出来了,大力模板。Sky 提交 M 题 RE,我去瞅了眼,发现三点共线导致分母为 0 0 0,立马帮他改成了叉积写法。之后又 WA,看了半天发现是 INF 开的不够大,红温……好在 3.5h 内通过。
然后我开始写 E 的字典树,写了半天发现巨丑还会运行错误,果断叫上 Zlw 来写,在提交了几发后发现神秘错误,在封榜后通过。之后就是 F,和队友确定了线段树二分写法,但是似乎和他的码风不太一样,于是被踹下来。但是由于写得有点屎,赛时没过,知道赛后 40 min 后通过该题。
最后赛时 8 8 8 题首尾(主要由 Zlw 写了一大半的题 orzorzorz,以及 Sky 的难题攻克)!
F 题有点深刻,自己又写了一遍。终于琢磨出为什么赛时会有这么多队伍过,原来还有两支 log \log log 的弱智写法。还是写一下线段树二分的做法吧,借鉴了一下题解,时间复杂度 O ( ∑ k log n ) O(\sum k \log n) O(∑klogn)。
#include <bits/stdc++.h>
#define init(x) memset (x,0,sizeof (x))
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define pii pair <int,int>
using namespace std;
const int MAX = 4e6 + 50;
const int MOD = 1e9 + 7;
inline int read ();
int t,n,q,cnt,ls[MAX],rs[MAX],tree[MAX];
class BIT
{
int n;vector <ll> c;
int lowbit (int x) {return x & (-x);}
public :
BIT (int n) : n (n),c (n + 1,0) {}
void modify (int x,int v) {for (int i = x;i <= n;i += lowbit (i)) c[i] += v;}
ll query (int x) {ll res = 0;for (int i = x;i;i -= lowbit (i)) res += c[i];return res;}
};
void modify (int &cur,int l,int r,int x,int v)
{
if (!cur) cur = ++cnt,ls[cur] = rs[cur] = tree[cur] = 0;
tree[cur] += v;
if (l == r) return ;
int mid = (l + r) >> 1;
if (x <= mid) modify (ls[cur],l,mid,x,v);
else modify (rs[cur],mid + 1,r,x,v);
}
int calc (vector <int> cur)
{
int res = 0;
for (auto v : cur) res += tree[v];
return res;
}
vector <int> next_L (vector <int> cur)
{
for (auto &v : cur) v = ls[v];
return cur;
}
vector <int> next_R (vector <int> cur)
{
for (auto &v : cur) v = rs[v];
return cur;
}
int search_L (vector <int> cur,int l,int r,int pos)
{
if (calc (cur) == r - l + 1) return 0;
if (l == r) return l;
int mid = (l + r) >> 1;
if (pos <= mid) return search_L (next_L (cur),l,mid,pos);
else
{
int res = search_L (next_R (cur),mid + 1,r,pos);
if (!res) return search_L (next_L (cur),l,mid,pos);
else return res;
}
}
int search_R (vector <int> cur,int l,int r,int pos)
{
if (calc (cur) == r - l + 1) return n + 1;
if (l == r) return l;
int mid = (l + r) >> 1;
if (pos > mid) return search_R (next_R (cur),mid + 1,r,pos);
else
{
int res = search_R (next_L (cur),l,mid,pos);
if (res == n + 1) return search_R (next_R (cur),mid + 1,r,pos);
else return res;
}
}
int main ()
{
t = read ();
while (t--)
{
n = read ();q = read ();cnt = 0;
vector <int> val (n + 1),col (n + 1),rt (n + 1,0);
BIT tr (n);
for (int i = 1;i <= n;++i) col[i] = read (),modify (rt[col[i]],1,n,i,1);
for (int i = 1;i <= n;++i) val[i] = read (),tr.modify (i,val[i]);
while (q--)
{
int ty = read ();
if (ty == 1)
{
int p = read (),x = read ();
modify (rt[col[p]],1,n,p,-1);
col[p] = x;
modify (rt[col[p]],1,n,p,1);
}
else if (ty == 2)
{
int p = read (),v = read ();
tr.modify (p,v - val[p]);
val[p] = v;
}
else
{
int st = read (),k = read ();
vector <int> p;
for (int i = 1;i <= k;++i)
{
int x = read ();
p.push_back (rt[x]);
}
int l = search_L (p,1,n,st),r = search_R (p,1,n,st);
printf ("%lld\n",tr.query (r - 1) - tr.query (l + 1 - 1));
}
}
}
return 0;
}
inline int read ()
{
int s = 0;int f = 1;
char ch = getchar ();
while ((ch < '0' || ch > '9') && ch != EOF)
{
if (ch == '-') f = -1;
ch = getchar ();
}
while (ch >= '0' && ch <= '9')
{
s = s * 10 + ch - '0';
ch = getchar ();
}
return s * f;
}