【题目大意】

求有多少区间只包含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. 软工实践-Alpha 冲刺 (1/10)

    队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 学习了UI设计软件的使用,了解了项目开发的具体流程. 展示 ...

  2. java — 垃圾回收

    1. 垃圾回收的意义 在java中,当没有对象指向原先分配给某个对象的内存的时候,这片内存就变成了垃圾,JVM的一个系统级线程就会自动释放这个内存块,垃圾回收意味着程序不再需要的对象是“无用的信息”, ...

  3. Spring Boot(六)自定义事件及监听

    事件及监听并不是SpringBoot的新功能,Spring框架早已提供了完善的事件监听机制,在Spring框架中实现事件监听的流程如下: 自定义事件,继承org.springframework.con ...

  4. C#控件DropDownList下拉列表默认打开

    c#中的控件DropDownList要实现默打开确实不容易,之前也是想过页面上的点击之后就打开了,那直接模拟点击不就行了,试过后大失所望,根本没有效果. 于是网上找到了一个例子能实现IE浏览器下的打开 ...

  5. DOS工具

    winver  检查Windows版本wmimgmt.msc  打开windows管理体系结构wupdmgr  windows更新程序wscript  windows脚本宿主设置write  写字板w ...

  6. Jmeter系列-自动生成html报告

    从JMeter 3.0开始已支持自动生成动态报告,我们可以更容易根据生成的报告来完成我们的性能测试报告. 如何生成html测试报告 如果未生成结果文件(.jtl),可运行如下命令生成报告: jmete ...

  7. 使用oledb读取excel表

    string path = "C:\\Users\\aaa\\Desktop\\aa.xls"; string conn = "Provider = Microsoft. ...

  8. 同步锁(synchronized)使用三要素

    1.代码被多个线程访问 2.代码中有共享的数据 3.共享数据被多个语句操作

  9. 【bzoj3631】[JLOI2014]松鼠的新家 LCA+差分数组

    题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀请小熊维尼前来 ...

  10. C# 类反射创建对象实例

    object obj= Activator.CreateInstance(Type  type);