这题又是万恶的线段树

maxx[j]存储的是 l = xxx, r = j的时候的答案

我们会让 l 从 1到n 的遍历中,查询线段树的[l, n]中最大的答案

因为query的下界是n,所以单次查询复杂度是logn

再其次这样做必须得再每次单元操作之后 对线段树 进行update

#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <map>
#include <bitset>
#include <algorithm>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <functional>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <deque>
#include <stack>
#include <complex>
#include <cassert>
#include <random>
#include <cstring>
#include <numeric>
#define ll long long
#define ld long double
#define null NULL
#define all(a) a.begin(), a.end()
#define forn(i, n) for (int i = 0; i < n; ++i)
#define sz(a) (int)a.size()
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
template<class T> int gmax(T &a, T b) { if (b > a) { a = b; return 1; } return 0; }
template<class T> int gmin(T &a, T b) { if (b < a) { a = b; return 1; } return 0; }
using namespace std; int n, s;
const int N = 1e5 + 5;
int A[N]; // origin input array
vector<int> pos[N]; // positions in initial array split by its value
int nowSize[N]; // the order of A[i] in their own position array
int input[N]; // use for segment tree input int maxx[N << 2];
int lazy[N << 2]; void pushUp(int rt) {
maxx[rt] = max(maxx[rt << 1], maxx[rt << 1 | 1]);
} void pushDown(int rt) {
if(lazy[rt]) {
maxx[rt << 1] += lazy[rt];
maxx[rt << 1 | 1] += lazy[rt];
lazy[rt << 1] += lazy[rt];
lazy[rt << 1 | 1] += lazy[rt];
lazy[rt] = 0;
}
} void build(int l, int r, int rt) {
lazy[rt] = 0;
if(l == r) {
maxx[rt] = input[l];
return;
}
int m = (l + r) >> 1;
build(lson); build(rson);
pushUp(rt);
} int query(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) return maxx[rt]; pushDown(rt);
int m = (l + r) >> 1;
int ret = -1;
if(L <= m) ret = max(ret, query(L, R, lson));
if(R > m) ret = max(ret, query(L, R, rson));
return ret;
} void update(int c, int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) {
maxx[rt] += c;
lazy[rt] += c;
return;
}
pushDown(rt);
int m = (l + r) >> 1;
if(L <= m) update(c, L, R, lson);
if(R > m) update(c, L, R, rson);
pushUp(rt);
} int main() {
int T;
scanf("%d", &T);
for(int cas = 1; cas <= T; ++ cas) {
scanf("%d %d", &n, &s);
for(int i = 0; i < N; ++i) pos[i].clear();
for(int i = 1; i <= n; ++i) scanf("%d", &A[i]); for(int i = 1; i <= n; ++i) {
pos[A[i]].push_back(i);
nowSize[i] = pos[A[i]].size();
} for(int i = 0; i < N; ++i) pos[i].push_back(n + 1);
input[0] = 0;
for(int i = 1; i <= n; ++i) {
input[i] = input[i-1] + 1;
if(nowSize[i] == s + 1) input[i] -= s + 1;
else if(nowSize[i] > s + 1) input[i] --;
}
build(1, n, 1);
int ans = -1;
for(int i = 1; i <= n; ++i) {
ans = max(ans, query(i, n, 1, n, 1));
int num = A[i];
if(nowSize[i] + s < pos[num].size()) {
int tmp = pos[num][nowSize[i] + s - 1];
int tmp2 = pos[num][nowSize[i] + s]; update(-1, i, tmp - 1, 1, n, 1);
update(s, tmp, tmp2 - 1, 1, n, 1);
} else {
update(-1, i, n, 1, n, 1);
}
} printf("Case #%d: %d\n", cas, ans); }
return 0;
}

Google Kickstart Round.B C. Diverse Subarray的更多相关文章

  1. google Kickstart Round G 2017 三道题题解

    A题:给定A,N,P,计算A的N!次幂对P取模的结果. 数据范围: T次测试,1 ≤ T ≤ 100 1<=A,N,P<=105 快速幂一下就好了.O(nlogn). AC代码: #inc ...

  2. 2019 google kickstart round A

    第一题: n个人,每个人有一个对应的技能值s,现在要从n个人中选出p个人,使得他们的技能值相同. 显然,如果存在p个人的技能值是相同的,输出0就可以了.如果不存在,就要找出p个人,对他们进行训练,治他 ...

  3. google Kickstart Round F 2017 四道题题解

    Problem A. Kicksort 题意抽象一下为: 对于一个每次都从数列正中间取划分数的快速排序,给定一个1-n的排列,问快排的复杂度对于这个排列是否会退化为最坏复杂度. 数据范围: 测试组数1 ...

  4. Google Kickstart Round E 2018 B. Milk Tea

    太蠢了,,,因为初始化大数据没过,丢了10分,纪念一下这个错误 大概思路:先求出让损失值最小的排列,由已生成的这些排列,通过更改某一个位置的值,生成下一个最优解,迭代最多生成m+1个最优解即可,遍历求 ...

  5. Google Kickstart在线测试规则以及注意事项

    谷歌招聘在如火如荼的进行中,进谷歌都需要经过谷歌kickstart在线测试,然后过了之后还有五轮的面试- -.好吧毕竟你待遇高,你强你有理.. 下面介绍一下进谷歌的第一关google kickstar ...

  6. Google kickstart 2022 Round A题解

    Speed Typing 题意概述 给出两个字符串I和P,问能否通过删除P中若干个字符得到I?如果能的话,需要删除字符的个数是多少? 数据规模 \[1≤|I|,|P|≤10^5 \] 双指针 设置两个 ...

  7. google kickstart 2018 round D A Candies

    思路: 对于small数据,由于求和及奇数数量两个限制条件均满足区间单调性,可以直接使用尺取法(滑动窗口法)求解. 对于large数据,奇数数量依然是满足区间单调性的.首先使用尺取法,找到所有满足奇数 ...

  8. [Google Codejam] Round 1A 2016 - The Last Word

    [Problem Description] Problem On the game show The Last Word, the host begins a round by showing the ...

  9. Let Me Count The Ways(Kickstart Round H 2018)

    题目链接:https://code.google.com/codejam/contest/3324486/dashboard#s=p2 题目: 思路: 代码实现如下: #include <set ...

随机推荐

  1. 一段刚刚出炉的CSV文件转换为DataTable对象的代码

    CSV是以文本形式保存的表格数据,具体是每列数据使用逗号分割,每行数据使用CRLF(\r\n)来结尾,如果数据值包含逗号或CRLF则使用双引号将数值包裹,如果数据值包含双引号则使用两个双引号做为转义. ...

  2. 代理工具--mitmproxy

    #代理工具 mitmproxy 指令:mitmproxy -b ip -p port(代理ip设置为:ip,端口设置为:port) 拦截request: 输入字母“i”(代表Intercept fil ...

  3. 题解 P2920 【[USACO08NOV]时间管理Time Management】

    题面 作为一名忙碌的商人,约翰知道必须高效地安排他的时间.他有N工作要 做,比如给奶牛挤奶,清洗牛棚,修理栅栏之类的. 为了高效,列出了所有工作的清单.第i分工作需要T_i单位的时间来完成,而 且必须 ...

  4. 极限编程核心价值:反馈(Feedback)

    原文:https://deviq.com/feedback 极限编程核心价值:简单(Simplicity) 极限编程核心价值:沟通(Communication) 极限编程核心价值:反馈(Feedbac ...

  5. 在Word2007,2010,2016中分栏但不换页的方法

    解决方法: word2007:界面左上角的按钮->选择word选项->依次点击“高级”->“版式选项”->点开加号,“按word6.x/95/97的方式排放脚注”. Word2 ...

  6. objc.io 待看文章

    https://objccn.io/issues/ https://objccn.io/issues/ 使用 VIPER 构建 iOS 应用 并发编程

  7. 为什么说swift是面向协议编程--草稿

    为什么说swift是面向协议编程 public protocol ReactiveCompatible { /// Extended type associatedtype CompatibleTyp ...

  8. P1231 教辅的组成

    传送门:https://www.luogu.org/problemnew/show/P1231 这是一道很不错的网络流入门题,关键在于如何建图. 首先,我们将练习册和源点连一条边权为1的边,然后若书 ...

  9. 面试题之O(n)内旋转字符串

    样例: 字符串“abcd1234"左移3位结果为”234abcd1“ K:左移位数 L:字符串长度 方案1:暴力 O(K * L) 可以每次将数组中的元素左移一位,循环K次. abcd123 ...

  10. nginx rewrite flag

    1.break可以理解为switch中的break,而last可以理解为continue,一个是跳出server{}的匹配规则,一个还将继续匹配之后的规则. 无论使用last还是break,浏览器上面 ...