图腾计数
题目描述
whitecloth 最近参观了楼兰图腾。图腾的所在地有一排\(N\)个柱子,\(N\)个柱子的高度恰好为一个1到N的排列,而楼兰图腾就隐藏在这些柱子中。
由于whitecloth弱爆了,他只知道图腾由3个柱子组成,这三个柱子组成了下凸或上凸的图形(>.<),所谓下凸,设三个柱子的高度从左到右依次为 \(h1,h2,h3\),那么\(h1>h2,h3>h2\),上凸则满足\(h1<h2,h3<h2\)。
现在whitecloth也找不到图腾具体是哪三个柱子,他只想知道满足这两个形状的柱子有几组。
输入格式
第一行一个数𝑁,接下来一行𝑁个数,依次表示每个柱子的高度
输出格式
一行两个数,表示下凸形状的数量和上凸形状的数量,用空格隔开
样例
样例输入
5
1 5 3 2 4
样例输出
3 4
数据范围与提示
\(𝑁≤200000\)
code
#include <bits/stdc++.h>
using namespace std;
const int maxn = 200 + 10;
char c[maxn];
int s, n, m;
int h[maxn][maxn];
struct node {
int t, next;
} e[maxn * maxn * 8];
int head[maxn * maxn], f[maxn * maxn], jl[maxn * maxn];
int near[maxn * maxn];
int v[maxn * maxn];
int tot = 0;
void add(int x, int y, int z) {
f[x] = 1;
e[++tot] = (node){ y, head[x] };
head[x] = tot;
if (z == 1)
jl[x]++;
else
near[x]++;
}
void add1(int x, int y, int k) {
add(h[x][y + 1], h[x + 1][y], k);
add(h[x + 1][y], h[x][y + 1], k);
}
void add2(int x, int y, int k) {
add(h[x][y], h[x + 1][y + 1], k);
add(h[x + 1][y + 1], h[x][y], k);
}
void read(int k) {
for (int i = 1; i <= n; i++) {
scanf("%s", c + 1);
for (int j = 1; j <= m; j++)
if (c[j] == 'X')
add1(i, j, k), add2(i, j, k);
else if (c[j] == '/')
add1(i, j, k);
else if (c[j] == '\\')
add2(i, j, k);
}
}
void dfs(int x) {
v[x] = 1;
s += abs(jl[x] - near[x]);
for (int i = head[x]; i; i = e[i].next)
if (!v[e[i].t])
dfs(e[i].t);
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n + 1; i++)
for (int j = 1; j <= m + 1; j++) h[i][j] = (i - 1) * (m + 1) + j;
read(1);
read(-1);
int ans = 0;
for (int i = 1; i <= n + 1; i++)
for (int j = 1; j <= m + 1; j++) {
int x = h[i][j];
if (!f[x] || v[x])
continue;
s = 0;
dfs(x);
if (s == 0)
s = 1;
else if (s != 0)
s = s / 2;
ans += s;
}
cout << ans;
return 0;
}