省队集训 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\) 个点后这个图没有环. 问在不删去钦定的这 \ ...
随机推荐
- iOS- <项目笔记>iOS6 & iOS7屏幕图片适配
1.为非视网膜\视网膜屏幕分别准备2份图片,比如: 1> 非视网膜 abc.png 2> 视网膜 abc@2x.png 程序检测视网膜屏到会自动替换@2x 2.程序启动图片 * 程序启动过 ...
- oracle 时间段内的所有行时间
获取一段时间内所有的小时 SELECT to_date('2013-07-01 12', 'yyyy-mm-dd hh24') + (ROWNUM - 1) / 24 sdate FROM dualC ...
- Java设计
重构前 CustomDataChar | getConnection()findCustomers()createChar()displayChar() 重构后 CustomDataChar | da ...
- shit antd & Merry Christmas bug
shit antd & Merry Christmas bug https://github.com/ant-design/ant-design/issues/13098 antd 玩大了? ...
- BZOJ 口胡记录
最近实在是懒的不想打代码...好像口胡也算一种训练,那就口胡把. BZOJ 2243 染色(树链剖分) 首先树链剖分,然后记录下每个区间的左右端点颜色和当前区间的颜色段.再对每个节点维护一个tag标记 ...
- BZOJ4737 组合数问题(卢卡斯定理+数位dp)
不妨不管j<=i的限制.由卢卡斯定理,C(i,j) mod k=0相当于k进制下存在某位上j大于i.容易想到数位dp,即设f[x][0/1][0/1][0/1]为到第x位时是否有某位上j> ...
- hdu 3191 How Many Paths Are There (次短路径数)
How Many Paths Are There Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java ...
- (转) Parameter estimation for text analysis 暨LDA学习小结
Reading Note : Parameter estimation for text analysis 暨LDA学习小结 原文:http://www.xperseverance.net/blogs ...
- 【刷题】BZOJ 1002 [FJOI2007]轮状病毒
Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子 和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下 ...
- AOJ.866 飞越原野 (三维BFS)
AOJ.866 飞越原野 (三维BFS) 题意分析 点我挑战题目 相比于普通的BFS,要多一维来记录当前剩余的体力.而且还要额外的一层循环来处理,飞过的路程. 代码总览 #include <io ...