【USACO 2021 US Open, Platinum】United Cows of Farmer John
\(\text{Solution}\)
简要的口胡
线段树维护合法左端点数量
正序枚举 \(i\),将其视为右端点,去除不合法的左端点,统计贡献
再将其视为中间点,由它产生的左端点在线段树上区间加
注意到一个重复出现的 \(b\) 值,上一个相同位置的贡献不能再要
于是把这个点废掉
考场上又打了棵线段树,统计答案的线段树只需去掉被废掉的点即可
直接跑了 \(949ms\),两只 \(\text{log}\) 踩线过(后时限开到 \(2s\),不算踩线了,可仍然垫底)
\(\text{Code}\)
#include <cstdio>
#include <algorithm>
#define ls (p << 1)
#define rs (ls | 1)
#define re register
#define LL long long
using namespace std;
const int N = 2e5 + 5;
int n, b[N], l1[N], l2[N];
LL ans;
int sum[N << 2], tag[N << 2], del[N << 2];
inline void remove(int p, int l, int r, int x)
{
if (x < l || x > r) return;
if (l == r) return void(del[p] = 1);
int mid = (l + r) >> 1;
if (x <= mid) remove(ls, l, mid, x);
else remove(rs, mid + 1, r, x);
del[p] = del[ls] + del[rs];
}
inline int count(int p, int l, int r, int x, int y)
{
if (x > y || y < l || x > r) return 0;
if (x <= l && r <= y) return del[p];
int mid = (l + r) >> 1, res = 0;
if (x <= mid) res = count(ls, l, mid, x, y);
if (y > mid) res += count(rs, mid + 1, r, x, y);
return res;
}
inline void pushdown(int p, int l, int r)
{
if (!tag[p]) return;
int mid = (l + r) >> 1;
sum[ls] += (mid - l + 1 - count(1, 1, n, l, mid)) * tag[p], tag[ls] += tag[p];
sum[rs] += (r - mid - count(1, 1, n, mid + 1, r)) * tag[p], tag[rs] += tag[p];
tag[p] = 0;
}
void update(int p, int l, int r, int x, int y, int v)
{
if (x > y || y < l || x > r) return;
if (x <= l && r <= y)
{
sum[p] += v * (r - l + 1 - count(1, 1, n, l, r)), tag[p] += v;
return;
}
pushdown(p, l, r);
int mid = (l + r) >> 1;
if (x <= mid) update(ls, l, mid, x, y, v);
if (y > mid) update(rs, mid + 1, r, x, y, v);
sum[p] = sum[ls] + sum[rs];
}
int query(int p, int l, int r, int x, int y)
{
if (x > y || y < l || x > r) return 0;
if (x <= l && r <= y) return sum[p];
pushdown(p, l, r);
int mid = (l + r) >> 1, res = 0;
if (x <= mid) res = query(ls, l, mid, x, y);
if (y > mid) res += query(rs, mid + 1, r, x, y);
return res;
}
int main()
{
scanf("%d", &n);
for(re int i = 1; i <= n; i++) scanf("%d", &b[i]);
for(re int i = 1; i <= n; i++)
{
update(1, 1, n, l2[b[i]] + 1, l1[b[i]] - 1, -1);
update(1, 1, n, l1[b[i]], l1[b[i]], -query(1, 1, n, l1[b[i]], l1[b[i]]));
remove(1, 1, n, l1[b[i]]), ans += query(1, 1, n, l1[b[i]] + 1, i - 2);
update(1, 1, n, l1[b[i]] + 1, i - 1, 1), l2[b[i]] = l1[b[i]], l1[b[i]] = i;
}
printf("%lld\n", ans);
}
其实只需将第二个线段树改为树状数组,尽管还是两只 \(\text{log}\),但快了很多
\(\text{Code}\)
#include <cstdio>
#include <algorithm>
#define ls (p << 1)
#define rs (ls | 1)
#define re register
#define LL long long
using namespace std;
const int N = 2e5 + 5;
int n, b[N], l1[N], l2[N], c[N];
LL ans;
int sum[N << 2], tag[N << 2], del[N << 2];
inline int lowbit(int x){return x & (-x);}
inline void remove(int x, int v)
{
if (!x) return;
for(; x <= n; x += lowbit(x)) c[x] += v;
}
inline int querysum(int x)
{
if (!x) return 0;
int res = 0;
for(; x; x -= lowbit(x)) res += c[x];
return res;
}
inline int count(int x, int y){return querysum(y) - querysum(x - 1);}
inline void pushdown(int p, int l, int r)
{
if (!tag[p]) return;
int mid = (l + r) >> 1;
sum[ls] += (mid - l + 1 - count(l, mid)) * tag[p], tag[ls] += tag[p];
sum[rs] += (r - mid - count(mid + 1, r)) * tag[p], tag[rs] += tag[p];
tag[p] = 0;
}
void update(int p, int l, int r, int x, int y, int v)
{
if (x > y || y < l || x > r) return;
if (x <= l && r <= y)
{
sum[p] += v * (r - l + 1 - count(l, r)), tag[p] += v;
return;
}
pushdown(p, l, r);
int mid = (l + r) >> 1;
if (x <= mid) update(ls, l, mid, x, y, v);
if (y > mid) update(rs, mid + 1, r, x, y, v);
sum[p] = sum[ls] + sum[rs];
}
int query(int p, int l, int r, int x, int y)
{
if (x > y || y < l || x > r) return 0;
if (x <= l && r <= y) return sum[p];
pushdown(p, l, r);
int mid = (l + r) >> 1, res = 0;
if (x <= mid) res = query(ls, l, mid, x, y);
if (y > mid) res += query(rs, mid + 1, r, x, y);
return res;
}
int main()
{
scanf("%d", &n);
for(re int i = 1; i <= n; i++) scanf("%d", &b[i]);
for(re int i = 1; i <= n; i++)
{
update(1, 1, n, l2[b[i]] + 1, l1[b[i]] - 1, -1);
update(1, 1, n, l1[b[i]], l1[b[i]], -query(1, 1, n, l1[b[i]], l1[b[i]]));
remove(l1[b[i]], 1), ans += query(1, 1, n, l1[b[i]] + 1, i - 2);
update(1, 1, n, l1[b[i]] + 1, i - 1, 1), l2[b[i]] = l1[b[i]], l1[b[i]] = i;
}
printf("%lld\n", ans);
}
其实要在线段树上废掉一个点,只要将这个线段树带上系数,把这一位系数改成 \(0\) 即可
\(Code\)
#include <cstdio>
#include <algorithm>
#define ls (p << 1)
#define rs (ls | 1)
#define re register
#define LL long long
using namespace std;
const int N = 2e5 + 5;
int n, b[N], l1[N], l2[N];
LL ans;
int sum[N << 2], tag[N << 2], c[N << 2];
inline void pushdown(int p, int l, int r)
{
if (!tag[p]) return;
int mid = (l + r) >> 1;
sum[ls] += c[ls] * tag[p], tag[ls] += tag[p];
sum[rs] += c[rs] * tag[p], tag[rs] += tag[p];
tag[p] = 0;
}
inline void change(int p, int l, int r, int x, int v)
{
if (x < l || x > r) return;
if (l == r)
{
c[p] = v, sum[p] = v * tag[p];
return;
}
pushdown(p, l, r);
int mid = (l + r) >> 1;
if (x <= mid) change(ls, l, mid, x, v);
else change(rs, mid + 1, r, x, v);
sum[p] = sum[ls] + sum[rs], c[p] = c[ls] + c[rs];
}
void update(int p, int l, int r, int x, int y, int v)
{
if (x > y || y < l || x > r) return;
if (x <= l && r <= y)
{
sum[p] += v * c[p], tag[p] += v;
return;
}
pushdown(p, l, r);
int mid = (l + r) >> 1;
if (x <= mid) update(ls, l, mid, x, y, v);
if (y > mid) update(rs, mid + 1, r, x, y, v);
sum[p] = sum[ls] + sum[rs], c[p] = c[ls] + c[rs];
}
int query(int p, int l, int r, int x, int y)
{
if (x > y || y < l || x > r) return 0;
if (x <= l && r <= y) return sum[p];
pushdown(p, l, r);
int mid = (l + r) >> 1, res = 0;
if (x <= mid) res = query(ls, l, mid, x, y);
if (y > mid) res += query(rs, mid + 1, r, x, y);
return res;
}
int main()
{
scanf("%d", &n);
for(re int i = 1; i <= n; i++) scanf("%d", &b[i]);
for(re int i = 1; i <= n; i++)
{
update(1, 1, n, l2[b[i]] + 1, l1[b[i]] - 1, -1), change(1, 1, n, l1[b[i]], 0);
ans += query(1, 1, n, l1[b[i]] + 1, i - 2);
update(1, 1, n, l1[b[i]] + 1, i - 1, 1), change(1, 1, n, i, 1);
l2[b[i]] = l1[b[i]], l1[b[i]] = i;
}
printf("%lld\n", ans);
}
【USACO 2021 US Open, Platinum】United Cows of Farmer John的更多相关文章
- 孤独的照片【USACO 2021 December Contest Bronze】
孤独的照片 Farmer John 最近购入了 \(N\) 头新的奶牛,每头奶牛的品种是更赛牛(Guernsey)或荷斯坦牛(Holstein)之一. 奶牛目前排成一排,Farmer John 想要为 ...
- 洛谷 P2812 校园网络【[USACO]Network of Schools加强版】 解题报告
P2812 校园网络[[USACO]Network of Schools加强版] 题目背景 浙江省的几所OI强校的神犇发明了一种人工智能,可以AC任何题目,所以他们决定建立一个网络来共享这个软件.但是 ...
- P2812 校园网络【[USACO]Network of Schools加强版】
题目背景 浙江省的几所OI强校的神犇发明了一种人工智能,可以AC任何题目,所以他们决定建立一个网络来共享这个软件.但是由于他们脑力劳动过多导致全身无力身体被♂掏♂空,他们来找你帮助他们. 题目描述 共 ...
- luogu P2812 校园网络【[USACO]Network of Schools加强版】|Tarjan
题目背景 浙江省的几所OI强校的神犇发明了一种人工智能,可以AC任何题目,所以他们决定建立一个网络来共享这个软件.但是由于他们脑力劳动过多导致全身无力身体被♂掏♂空,他们来找你帮助他们. 题目描述 共 ...
- 【USACO 2.1.1】城堡
[题目描述] 我们憨厚的USACO主人公农夫约翰(Farmer John)以无法想象的运气,在他生日那天收到了一份特别的礼物:一张“幸运爱尔兰”(一种彩票).结果这张彩票让他获得了这次比赛唯一的奖品— ...
- 【USACO】草地排水
Drainage Ditches 草地排水 usaco 4.2.1描述在农夫约翰的农场上,每逢下雨,Bessie最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一 ...
- POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 【USACO】距离咨询(最近公共祖先)
POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 [USACO]距离咨询(最近公共祖先) Description F ...
- 题解 【USACO 4.2.1】草地排水
[USACO 4.2.1]草地排水 Description 在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水.这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间.因此,农夫 ...
- 1642: 【USACO】Payback(还债)
1642: [USACO]Payback(还债) 时间限制: 1 Sec 内存限制: 64 MB 提交: 190 解决: 95 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述 &quo ...
- 1519: 【USACO】超级书架
1519: [USACO]超级书架 时间限制: 1 Sec 内存限制: 64 MB 提交: 1735 解决: 891 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述 Farmer Jo ...
随机推荐
- Java Web中requset,session,application 的作用域及区别
三者概述 requset概述: request是表示一个请求,只要发出一个请求就会创建一个request 用处:常用于服务器间同一请求不同页面之间的参数传递,常应用于表单的控件值传递. session ...
- Linux相关命令及软件安装教程
@font-face { font-family: "Times New Roman" } @font-face { font-family: "宋体" } @ ...
- 【每日一题】【递归+int型返回值最后不接收】110. 平衡二叉树-211231/220221
给定一个二叉树,判断它是否是高度平衡的二叉树. 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 . 答案: public class Solution ...
- 云原生架构(二)环境搭建(Mac上安装Docker+Kubernetes+Istio一条龙)
一.背景 Istio 项目由 Google 和 IBM 的团队与 Lyft 的 Envoy 团队合作启动.它已经完全在 GitHub 上公开开发.目前已经是"Service Mesh服务网格 ...
- Qt网络编程-从0到多线程编程
网络编程开发 1.简介 两个协议,一个是TCP协议,一个是UDP协议 先说TCP: TCP的话,服务器端需要端口监听,直到有客户端进行连接发送过来请求数据,然后客户端根据请求数据进行应答,之后就算tc ...
- 从源码层面深度剖析Spring循环依赖
作者:郭艳红 以下举例皆针对单例模式讨论 图解参考 https://www.processon.com/view/link/60e3b0ae0e3e74200e2478ce 1.Spring 如何创建 ...
- 深度学习之Transformer网络
[博主使用的python版本:3.6.8] 本次没有额外的资料下载 Packages ort tensorflow as tf import pandas as pd import time impo ...
- python进阶之路7 数据类型的内置方法
内容回顾 while 循环补充说明 1.死循环 2.while循环嵌套和全局标志位 for循环 1.for 变量名 in 待遍历数据 for循环体代码 2.for 也可以与break continue ...
- 蓝桥真题——最短路 & 门牌制作
题目1 最短路 标签:填空题 2019 省赛 如下图所示,G 是一个无向图,其中蓝色边的长度是 1.橘色边的长度是 2.绿色边的长度是 3. 则从 A 到 S 的最短距离是多少? 答案 由图可得,最短 ...
- GreenPlum批量授权(PG未测试)
创建一个自定义function create or replace function grant_all_exec(schema_name varchar,select_or_insert varch ...