这题又是万恶的线段树

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. linux命令1—安装optimizer

    ZendChina官方:下面介绍一下关于在linux环境下Zend Optimizer 3.3的安装方法.本篇文章是基于RHEL5架构的linux系统. (1)ZendOptimizer 3.3.3版 ...

  2. js将时间戳转换成日期格式-陈远波

    var timestamp =1539598555000;//时间戳 //时间戳转换成time格式function timestampToTime(timestamp) { var date = ne ...

  3. apache 虚拟主机及phpmyadmin 配置

    NameVirtualHost *:80 <VirtualHost *:80> ServerName www.ly.comDocumentRoot E:/mywww </Virtua ...

  4. 加载驱动三种execute

    executeQuery executeUpdate executeQueryBatch

  5. 二、git版本回退

    查看历史版本提交记录 git log git log --pretty=oneline Git用 HEAD表示当前版本 commit id(版本号),也就是最新的提交e4aa53d...43ae6f6 ...

  6. 2-6 R语言基础 缺失值

    #缺失值 Missing Value > #NaN不可识别NA> x <- c(1,NA,2,NA,3) > is.na(x)[1] FALSE TRUE FALSE TRUE ...

  7. 1036. [ZJOI2008]树的统计【树链剖分】

    Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u t : 把结点u的权值改为t II. ...

  8. MP实战系列(十)之SpringMVC集成SpringFox+Swagger2

    该示例基于之前的实战系列,如果公司框架是使用JDK7以上及其Spring+MyBatis+SpringMVC/Spring+MyBatis Plus+SpringMVC可直接参考该实例. 不过建议最好 ...

  9. Linux下RPM包的安装

    Linux下RPM包安装 二进制包(RPM包.系统默认包) RPM安装 rpm -ivh 包全名(查询依赖网址:http://www.rpmfind.net) -i(install):安装 -v(ve ...

  10. jquery操作checked

    jquery操作checkbox,如何获取勾选状态?如何使得勾选?如何取消勾选? 来段代码就知道了: <html> <head> <meta charset=" ...