J. 大秦酒店欢迎您

题解

  • 我们考虑莫队

  • 首先我们预处理出处于位置\(x\)的颜色下一次出现的位置\(nxt[x]\)以及上一次出现的位置\(pre[x]\)

  • 莫队上维护一下信息:

\(Ans\):\([l,r]\)的所有子区间的颜色数之和

\(num\):\([l,r]\)的颜色数

\(Lans\):\([l,l],[l,l + 1],[l,l + 2]...[l,r]\)这些区间的颜色数之和

\(Rans\):\([r,r],[r - 1, r],[r - 2, r]...[l,r]\)这些区间的颜色数之和

\(cnt[x]\):颜色\(x\)的出现次数

  • 我们以左端点\(l\)向左扩张为例, 表示左端点向左扩张对维护的信息的影响

\(l:=l-1\)

\(cnt[col[l]]:=cnt[col[l]] + 1\),颜色出现次数更新的同时更新\(num\)

\(Rans:=Rans + num\)

\(Lans := Lans + min(r, nxt[l]-1) - l + 1\)

\(Ans := Ans + Lans\)

  • 那么对于其他操作的影响也是类似的
const int mod = (1ll << 32);
const int N = 5e5 + 10, M = 4e5 + 10;
const int B = sqrt(N) + 1; int n, q, a[N];
int id[N], Ans, Lans, Rans, num, cnt[N], nxt[N], pre[N], ans[N], pos[N]; struct QUERY
{
int l, r, idx;
bool operator<(const QUERY &t) const
{
if (id[l] == id[t.l])
{
if (id[l] & 1)
return r < t.r;
else
return r > t.r;
}
else
return l < t.l;
}
} qry[N]; void del(int l, int r, int op)
{
if (op == 1) // Left
{
Ans -= Lans;
Lans -= min(r, nxt[l] - 1) - l + 1;
Rans -= num;
cnt[a[l]]--;
if (cnt[a[l]] == 0)
num--;
}
else // Right
{
Ans -= Rans;
Rans -= r - max(l, pre[r] + 1) + 1;
Lans -= num;
cnt[a[r]]--;
if (cnt[a[r]] == 0)
num--;
}
} void add(int l, int r, int op)
{
if (op == 1) // Left
{
cnt[a[l]]++;
if (cnt[a[l]] == 1)
num++;
Rans += num;
Lans += min(r, nxt[l] - 1) - l + 1;
Ans += Lans;
}
else // Right
{
cnt[a[r]]++;
if (cnt[a[r]] == 1)
num++;
Lans += num;
Rans += r - max(l, pre[r] + 1) + 1;
Ans += Rans;
}
} void solve()
{
cin >> n >> q;
for (int i = 1; i <= n; ++i)
{
cin >> a[i];
pre[i] = 0;
if (pos[a[i]])
{
pre[i] = pos[a[i]];
nxt[pos[a[i]]] = i;
}
pos[a[i]] = i;
nxt[i] = n + 1;
}
for (int i = 1; i <= q; ++i)
{
cin >> qry[i].l >> qry[i].r;
qry[i].idx = i;
}
for (int i = 1; i <= n; ++i) // 分块
id[i] = (i - 1) / B + 1;
sort(qry + 1, qry + q + 1); // 对查询进行排序
for (int i = 1, l = 1, r = 0; i <= q; ++i)
{
while (l > qry[i].l)
add(--l, r, 1);
while (r < qry[i].r)
add(l, ++r, 2);
while (l < qry[i].l)
del(l++, r, 1);
while (r > qry[i].r)
del(l, r--, 2);
ans[qry[i].idx] = Ans;
}
for (int i = 1; i <= q; ++i)
cout << ans[i] % mod << endl;
}

M. 斑马子树

\(1 \leq n \leq 10^5\)

题解

  • 我们考虑如果一颗子树是斑马子树,那么这颗子树能够产生贡献的时间区间段是多少
  • 我们考虑\(dp\)出子树\(u\)中最早变成斑马子树的时间戳\(l\),最晚变成非斑马子树的时间戳\(r\)
  • 那么\([l,r]\)的时间段上\(u\)的贡献一直为\(1\),我们考虑差分,最后前缀和统计答案即可
// M. 斑马子树
const int N = 2e5 + 10, M = 4e5 + 10; int n, t[N], mi[N], mx[N], ans[N];
vector<int> g[N]; void dfs(int u, int par)
{
mi[u] = mx[u] = t[u];
for (auto v : g[u])
{
if (v == par)
continue;
dfs(v, u);
mi[u] = min(mi[u], mi[v]);
mx[u] = max(mx[u], mx[v]);
}
ans[mi[u]]++;
ans[mx[u]]--;
} void solve()
{
cin >> n;
for (int i = 2; i <= n; ++i)
{
int u;
cin >> u;
g[u].push_back(i);
g[i].push_back(u);
}
for (int i = 1; i <= n; ++i)
{
int u;
cin >> u;
t[u] = i;
}
dfs(1, 0);
for (int i = 1; i <= n; ++i)
{
ans[i] = ans[i - 1] + ans[i];
cout << ans[i] << "\n "[i < n];
}
}

随机推荐

  1. elementUI 时间线居左显示

    elementUI 时间线居左显示 一.vue + elementUI 实现时间线 Timellne 中时间戳居左显示 二.效果图 三.实现方法 关键代码: <el-timeline> & ...

  2. 技术实践 | 在线 KTV 实现过程(内附demo体验)

    ​ 你在线上K过歌吗? 在线K歌自2014年兴起以来,已经发展出了无比庞大的用户群体,每两人中就有就有一人体验过在线 K歌,其前景不可小觑. 如此庞大的市场规模,以及音视频技术使用门槛逐步降低的加持, ...

  3. ASP.NET Core – Configuration & Options

    前言 之前就写过 Asp.net core 学习笔记 ( Configuration 配置 ) 只是有点乱, 这篇作为整理版. 项目中会有许许多多的 Config 要设定. 比较好的管理方式是把它们放 ...

  4. Kubernetes Deployment控制器(二十)

    前面我们学习了 ReplicaSet 控制器,了解到该控制器是用来维护集群中运行的 Pod 数量的,但是往往在实际操作的时候,我们反而不会去直接使用 RS,而是会使用更上层的控制器,比如我们今天要学习 ...

  5. Hive----基本概念

    Hive 基本概念 1. Hive:由 Facebook 开源用于解决海量结构化日志的数据统计. 2. Hive 是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类 ...

  6. 腾讯自研Git客户端,助力每个人都可以轻松使用Git

    工具介绍 UGit是一款腾讯自研的Git客户端,为了让每个人都可以轻松使用Git,从而提高开发效率和团队协作的流畅性.支持工蜂MR/CR,工蜂议题管理,另外对于Git的原生特性有着深度支持. 支持的系 ...

  7. ARMv8中non-shareable inner-shareable outer-shareable属性

    如果将block的内存属性配置成Non-cacheable,那么数据就不会被缓存到cache,那么所有observer看到的内存是一致的,也就说此时也相当于Outer Shareable. 其实官方文 ...

  8. /proc/pids/smaps

    Linux内存管理 -- /proc/{pid}/smaps讲解 基本介绍 /proc/PID/smaps 文件是基于 /proc/PID/maps 的扩展,他展示了一个进程的内存消耗,比同一目录下的 ...

  9. 利用csv文件信息,将图片名信息保存到csv文件当中

    我们可以利用train.csv文件信息, 再结合给定的文件路径(path)信息,可以将给定字目录下的图片名信息整合到scv文件当中. train.csv文件格式: 图片名信息: 代码如下: from ...

  10. v-model 语法糖-在父子组件传值 的简写形式

    props的变量名字 必须是  value ,this.$emit('input',数据值) 的自定义事件必须是 input : v-model 是 vue 中进行数据双向绑定的指令,在内部实际上是通 ...