省队集训 Day4 a
【题目大意】
求有多少区间只包含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的更多相关文章
- FJ省队集训DAY4 T3
#include<cstdio> #include<iostream> #include<cmath> #include<cstring> #inclu ...
- FJ省队集训DAY4 T2
XXX #include<cstdio> #include<iostream> #include<cmath> #include<cstring> #i ...
- FJ省队集训DAY4 T1
直接上题解 #include<cstdio> #include<iostream> #include<cmath> #include<cstring> ...
- HN2018省队集训
HN2018省队集训 Day1 今天的题目来自于雅礼的高二学长\(dy0607\). 压缩包下载 密码: 27n7 流水账 震惊!穿着该校校服竟然在四大名校畅通无阻?霸主地位已定? \(7:10\)从 ...
- JS省队集训记
不知不觉省队集训已经结束,离noi也越来越近了呢 论考前实战训练的重要性,让我随便总结一下这几天的考试 Day 1 T1 唉,感觉跟xj测试很像啊?meet in middle,不过这种题不多测是什么 ...
- Loj #6069. 「2017 山东一轮集训 Day4」塔
Loj #6069. 「2017 山东一轮集训 Day4」塔 题目描述 现在有一条 $ [1, l] $ 的数轴,要在上面造 $ n $ 座塔,每座塔的坐标要两两不同,且为整点. 塔有编号,且每座塔都 ...
- Loj 6068. 「2017 山东一轮集训 Day4」棋盘
Loj 6068. 「2017 山东一轮集训 Day4」棋盘 题目描述 给定一个 $ n \times n $ 的棋盘,棋盘上每个位置要么为空要么为障碍.定义棋盘上两个位置 $ (x, y),(u, ...
- loj6068. 「2017 山东一轮集训 Day4」棋盘 二分图,网络流
loj6068. 「2017 山东一轮集训 Day4」棋盘 链接 https://loj.ac/problem/6068 思路 上来没头绪,后来套算法,套了个网络流 经典二分图 左边横,右边列 先重新 ...
- [2018HN省队集训D9T1] circle
[2018HN省队集训D9T1] circle 题意 给定一个 \(n\) 个点的竞赛图并在其中钦定了 \(k\) 个点, 数据保证删去钦定的 \(k\) 个点后这个图没有环. 问在不删去钦定的这 \ ...
随机推荐
- 软工实践-Alpha 冲刺 (1/10)
队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 学习了UI设计软件的使用,了解了项目开发的具体流程. 展示 ...
- java — 垃圾回收
1. 垃圾回收的意义 在java中,当没有对象指向原先分配给某个对象的内存的时候,这片内存就变成了垃圾,JVM的一个系统级线程就会自动释放这个内存块,垃圾回收意味着程序不再需要的对象是“无用的信息”, ...
- Spring Boot(六)自定义事件及监听
事件及监听并不是SpringBoot的新功能,Spring框架早已提供了完善的事件监听机制,在Spring框架中实现事件监听的流程如下: 自定义事件,继承org.springframework.con ...
- C#控件DropDownList下拉列表默认打开
c#中的控件DropDownList要实现默打开确实不容易,之前也是想过页面上的点击之后就打开了,那直接模拟点击不就行了,试过后大失所望,根本没有效果. 于是网上找到了一个例子能实现IE浏览器下的打开 ...
- DOS工具
winver 检查Windows版本wmimgmt.msc 打开windows管理体系结构wupdmgr windows更新程序wscript windows脚本宿主设置write 写字板w ...
- Jmeter系列-自动生成html报告
从JMeter 3.0开始已支持自动生成动态报告,我们可以更容易根据生成的报告来完成我们的性能测试报告. 如何生成html测试报告 如果未生成结果文件(.jtl),可运行如下命令生成报告: jmete ...
- 使用oledb读取excel表
string path = "C:\\Users\\aaa\\Desktop\\aa.xls"; string conn = "Provider = Microsoft. ...
- 同步锁(synchronized)使用三要素
1.代码被多个线程访问 2.代码中有共享的数据 3.共享数据被多个语句操作
- 【bzoj3631】[JLOI2014]松鼠的新家 LCA+差分数组
题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀请小熊维尼前来 ...
- C# 类反射创建对象实例
object obj= Activator.CreateInstance(Type type);