【题目大意】

求有多少区间只包含1个出现次数为1的数。

$1\leq n \leq 5*10^5, 0 \leq a_i \leq 10^9$

【题解】

考虑枚举右端点,设这个数上一次出现位置为pre[i],那么就是$[pre[i]+1,i]$区间加1,$[pre[pre[i]]+1, pre[i]]$区间减1,和统计区间中1的个数。

注意到数不会减到负的,那么1只可能是最小值或次小值,那么线段树直接维护即可。

复杂度$O(nlogn)$。

考场交错代码导致爆0...QAQ

# include <vector>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm> using namespace std; typedef long long ll;
typedef unsigned long long ull;
typedef long double ld; const int M = 5e5 + , N = 1e5 + , inf = 1e9; inline int getint() {
int x = ; char ch = getchar();
while(!isdigit(ch)) ch = getchar();
while(isdigit(ch)) x = (x<<) + (x<<) + ch - '', ch = getchar();
return x;
} int n, m, a[M], pre[M], lst[M];
vector<int> ps; struct pa {
int x, tx, y, ty;
pa() {}
pa(int x, int tx, int y, int ty) : x(x), tx(tx), y(y), ty(ty) {}
inline friend pa operator + (pa a, pa b) {
pa c;
if(a.x < b.x) {
c.x = a.x, c.tx = a.tx;
c.y = min(a.y, b.x); c.ty = ;
if(a.y == c.y) c.ty += a.ty;
if(b.x == c.y) c.ty += b.tx;
} else if(a.x > b.x) {
c.x = b.x, c.tx = b.tx;
c.y = min(a.x, b.y); c.ty = ;
if(a.x == c.y) c.ty += a.tx;
if(b.y == c.y) c.ty += b.ty;
} else {
c.x = a.x, c.tx = a.tx + b.tx;
c.y = min(a.y, b.y); c.ty = ;
if(a.y == c.y) c.ty += a.ty;
if(c.y == b.y) c.ty += b.ty;
}
return c;
}
}; struct SMT {
pa w[M << ]; int tag[M << ];
# define ls (x<<)
# define rs (x<<|)
inline void up(int x) {
w[x] = w[ls] + w[rs];
} inline void pushtag(int x, int t) {
w[x].x += t;
if(w[x].y != inf) w[x].y += t;
tag[x] += t;
} inline void down(int x) {
if(!tag[x]) return ;
pushtag(ls, tag[x]);
pushtag(rs, tag[x]);
tag[x] = ;
} inline void build(int x, int l, int r) {
if(l == r) {
w[x].x = , w[x].tx = ;
w[x].y = inf, w[x].ty = ;
return ;
}
int mid = l+r >> ;
build(ls, l, mid);
build(rs, mid+, r);
up(x);
} inline void edt(int x, int l, int r, int L, int R, int d) {
if(L <= l && r <= R) {
pushtag(x, d);
return ;
}
down(x);
int mid = l+r>>;
if(L <= mid) edt(ls, l, mid, L, R, d);
if(R > mid) edt(rs, mid+, r, L, R, d);
up(x);
} inline pa sum(int x, int l, int r, int L, int R) {
if(L <= l && r <= R) return w[x];
down(x);
int mid = l+r>>;
if(R <= mid) return sum(ls, l, mid, L, R);
else if(L > mid) return sum(rs, mid+, r, L, R);
else return sum(ls, l, mid, L, mid) + sum(rs, mid+, r, mid+, R);
} inline void debug(int x, int l, int r) {
printf("x = %d,l = %d,r = %d,mi = %d,semi = %d,minum = %d,seminum = %d,tag = %d\n", x, l, r, w[x].x, w[x].y, w[x].tx, w[x].ty, tag[x]);
if(l == r) return ;
int mid = l+r>>;
debug(ls, l, mid); debug(rs, mid+, r);
}
}T; int main() {
freopen("a1.in", "r", stdin);
// freopen("a.out", "w", stdout);
n = getint();
for (int i=; i<=n; ++i) {
a[i] = getint();
ps.push_back(a[i]);
}
sort(ps.begin(), ps.end());
ps.erase(unique(ps.begin(), ps.end()), ps.end());
m = ps.size();
for (int i=; i<=n; ++i) a[i] = lower_bound(ps.begin(), ps.end(), a[i]) - ps.begin() + ;
for (int i=; i<=n; ++i) pre[i] = lst[a[i]], lst[a[i]] = i;
ll ans = ; pa t; T.build(, , n);
for (int i=; i<=n; ++i) {
// T.debug(1, 1, n); cout << endl;
T.edt(, , n, pre[i] + , i, );
if(pre[i]) T.edt(, , n, pre[pre[i]] + , pre[i], -);
t = T.sum(, , n, , i);
if(t.x == ) ans += t.tx;
if(t.y == ) ans += t.ty;
// 区间加1,区间减1,查询区间内1的出现次数
}
cout << ans;
return ;
}

省队集训 Day4 a的更多相关文章

  1. FJ省队集训DAY4 T3

    #include<cstdio> #include<iostream> #include<cmath> #include<cstring> #inclu ...

  2. FJ省队集训DAY4 T2

    XXX #include<cstdio> #include<iostream> #include<cmath> #include<cstring> #i ...

  3. FJ省队集训DAY4 T1

    直接上题解 #include<cstdio> #include<iostream> #include<cmath> #include<cstring> ...

  4. HN2018省队集训

    HN2018省队集训 Day1 今天的题目来自于雅礼的高二学长\(dy0607\). 压缩包下载 密码: 27n7 流水账 震惊!穿着该校校服竟然在四大名校畅通无阻?霸主地位已定? \(7:10\)从 ...

  5. JS省队集训记

    不知不觉省队集训已经结束,离noi也越来越近了呢 论考前实战训练的重要性,让我随便总结一下这几天的考试 Day 1 T1 唉,感觉跟xj测试很像啊?meet in middle,不过这种题不多测是什么 ...

  6. Loj #6069. 「2017 山东一轮集训 Day4」塔

    Loj #6069. 「2017 山东一轮集训 Day4」塔 题目描述 现在有一条 $ [1, l] $ 的数轴,要在上面造 $ n $ 座塔,每座塔的坐标要两两不同,且为整点. 塔有编号,且每座塔都 ...

  7. Loj 6068. 「2017 山东一轮集训 Day4」棋盘

    Loj 6068. 「2017 山东一轮集训 Day4」棋盘 题目描述 给定一个 $ n \times n $ 的棋盘,棋盘上每个位置要么为空要么为障碍.定义棋盘上两个位置 $ (x, y),(u, ...

  8. loj6068. 「2017 山东一轮集训 Day4」棋盘 二分图,网络流

    loj6068. 「2017 山东一轮集训 Day4」棋盘 链接 https://loj.ac/problem/6068 思路 上来没头绪,后来套算法,套了个网络流 经典二分图 左边横,右边列 先重新 ...

  9. [2018HN省队集训D9T1] circle

    [2018HN省队集训D9T1] circle 题意 给定一个 \(n\) 个点的竞赛图并在其中钦定了 \(k\) 个点, 数据保证删去钦定的 \(k\) 个点后这个图没有环. 问在不删去钦定的这 \ ...

随机推荐

  1. 针对“来用”团队项目之NABC分析

    本项目特点之一:扩展性强 NABC分析: N(need):我们这个开发的这个软件主要是集娱乐软件和实用工具于一身的大容器,这里面有很多应用程序,针对不同用户需要,至少有一款应用程序能够满足用户的需要, ...

  2. 福大软工1816:Alpha(8/10)

    Alpha 冲刺 (8/10) 队名:第三视角 组长博客链接 本次作业链接 团队部分 团队燃尽图 工作情况汇报 张扬(组长) 过去两天完成了哪些任务: 文字/口头描述: 1. 2. 展示GitHub当 ...

  3. sql分页使用join提高性能

    今天在分析系统中的分页sql时意外知道了使用join可以提高分页性能. 逻辑是join部分使用单一表,单一字段排序分页,然后join大表.

  4. Java中的死锁问题

    死锁问题: 例如有两个线程, 线程1与线程2. 线程1在执行的过程中, 要锁定对象1, 2才能完成整个操作, 首先锁定对象1, 再锁定对象2. 线程2在执行的过程中, 要锁定对象2, 1才能完成整个操 ...

  5. [CLR via C#]引用类型和值类型

    一.引用类型与值类型的区别 CLR支持两种类型:引用类型和值类型.引用类型总是从托管堆上分配的,C#的new操作符会返回对象的内存地址.使用引用类型时,必须注意到一些性能问题. 1)内存必须从托管堆上 ...

  6. arp_annouce=2详解

    arp_annouce=0的时候 手册上说的是到底是是说当我这个包出去的时候询问arp地址, 当arp_announce=0的时候,是说使用数据包中的地址去进行arp的请求, 当arp_announc ...

  7. Redis 学习之主从复制

    该文使用centos6.5 64位    redis3.2.8 主从复制 Redis的复制功能是支持多个数据库之间的数据同步.一类是主数据库(master)一类是从数据库(slave),主数据库可以进 ...

  8. error C2143: 语法错误 : 缺少“;”(在“类型”的前面)

    C编程老是遇到这个问题: 错误 error C2143: 语法错误 : 缺少“;”(在“类型”的前面) d:\kinectproject\ceshiglad\ceshiglad\shili.c ces ...

  9. 当提交的表单类型为multipart/form-data时 后台的dopost则不能使用 setCharset来进行解码了 需要单独对字段使用 原始的new String(req.name("ISO-8859-1"),"utf-8")形式解码了

    当提交的表单类型为multipart/form-data时 后台的dopost则不能使用 setCharset来进行解码了 需要单独对字段使用 原始的new String(req.name(" ...

  10. Redis 基础:Redis 简介及安装

    Remote Dictionary Server(Redis)是一个由Salvatore Sanfilippo写的key-value存储系统.Redis是一个开源的使用ANSI C语言编写.遵守BSD ...