失踪人口回归
parent
ecb2c243c2
commit
e624bf1065
@ -0,0 +1,47 @@
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
int C[50050], bSize, res;
|
||||
template <typename T>
|
||||
T gcd(T a, T b) { return b == 0 ? a : gcd(b, a % b); }
|
||||
struct query
|
||||
{
|
||||
int l, r, id;
|
||||
} Q[50050];
|
||||
inline bool operator<(const query &lhs, const query &rhs) { return lhs.l / bSize == rhs.l / bSize ? lhs.r < rhs.r : lhs.l / bSize < rhs.l / bSize; }
|
||||
int ans[50050][2], cnt[50050];
|
||||
inline void ins(int x)
|
||||
{
|
||||
res -= cnt[x] * cnt[x];
|
||||
cnt[x]++;
|
||||
res += cnt[x] * cnt[x];
|
||||
}
|
||||
inline void del(int x)
|
||||
{
|
||||
res -= cnt[x] * cnt[x];
|
||||
cnt[x]--;
|
||||
res += cnt[x] * cnt[x];
|
||||
}
|
||||
int main()
|
||||
{
|
||||
int n, m;
|
||||
scanf("%d%d", &n, &m);
|
||||
while (bSize * bSize < n) bSize++;
|
||||
for (int i = 1; i <= n; i++) scanf("%d", C + i);
|
||||
for (int i = 0; i < m; i++) scanf("%d%d", &Q[i].l, &Q[i].r), Q[i].id = i;
|
||||
std::sort(Q, Q + m);
|
||||
for (int i = 0, L = 1, R = 0; i < m; i++)
|
||||
if (Q[i].l == Q[i].r)
|
||||
ans[Q[i].id][0] = 0, ans[Q[i].id][1] = 1;
|
||||
else
|
||||
{
|
||||
while (L < Q[i].l) del(C[L]), L++;
|
||||
while (R < Q[i].r) R++, ins(C[R]);
|
||||
while (L > Q[i].l) L--, ins(C[L]);
|
||||
while (R > Q[i].r) del(C[R]), R--;
|
||||
int range = Q[i].r - Q[i].l + 1;
|
||||
long long a = res - range, b = 1ll * range * (range - 1), c = gcd(a, b);
|
||||
ans[Q[i].id][0] = int(a / c), ans[Q[i].id][1] = int(b / c);
|
||||
}
|
||||
for (int i = 0; i < m; i++) printf("%d/%d\n", ans[i][0], ans[i][1]);
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,96 @@
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
inline void read(int &x) {
|
||||
int ch = x = 0, flag = 1;
|
||||
while (!isdigit(ch = getchar()))
|
||||
if (ch == '-') flag = -1;
|
||||
for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
|
||||
x *= flag;
|
||||
}
|
||||
template <typename T>
|
||||
inline T max(const T &x, const T &y) { return x > y ? x : y; }
|
||||
const int inf = 0x3f3f3f3f, N = 50005, M = 1000010;
|
||||
int adj[N], nxt[M << 1], to[M << 1], la[M << 1], lb[M << 1], ecnt;
|
||||
inline void addEdge(int f, int t, int a, int b) {
|
||||
ecnt++;
|
||||
nxt[ecnt] = adj[f];
|
||||
adj[f] = ecnt;
|
||||
to[ecnt] = t;
|
||||
la[ecnt] = a;
|
||||
lb[ecnt] = b;
|
||||
}
|
||||
int main() {
|
||||
int n, m, q, u, v, a, b;
|
||||
read(n), read(m);
|
||||
for (int i = 0; i < m; i++) {
|
||||
read(u), read(v), read(a), read(b);
|
||||
addEdge(u, v, a, b), addEdge(v, u, a, b);
|
||||
}
|
||||
read(q);
|
||||
static int que[M << 2];
|
||||
static bool vis[M << 1];
|
||||
if (m != n - 1) {
|
||||
while (q--) {
|
||||
read(u), read(v), read(a), read(b);
|
||||
memset(vis, 0, sizeof(vis));
|
||||
int len = 0;
|
||||
que[len++] = u;
|
||||
bool visv = false;
|
||||
int ma = -inf, mb = -inf;
|
||||
for (int i = 0; i < len; i++)
|
||||
for (int e = adj[u = que[i]]; e; e = nxt[e])
|
||||
if (!vis[e] && la[e] <= a && lb[e] <= b)
|
||||
ma = max(ma, la[e]), mb = max(mb, lb[e]), vis[e] = true, que[len++] = to[e];
|
||||
for (int i = 0; i < len && !visv; i++)
|
||||
if (que[i] == v) visv = true;
|
||||
puts((visv && ma == a && mb == b) ? "Yes" : "No");
|
||||
}
|
||||
} else {
|
||||
static int pos[N], A[M], B[M];
|
||||
memset(A, 0xc0, sizeof(A));
|
||||
memset(B, 0xc0, sizeof(B));
|
||||
int len = 0;
|
||||
vis[que[len++] = 1] = true;
|
||||
for (int i = 0; i < len; i++)
|
||||
for (int e = adj[que[i]]; e; e = nxt[e])
|
||||
if (!vis[to[e]])
|
||||
vis[que[len++] = to[e]] = true;
|
||||
memset(vis, 0, sizeof(vis));
|
||||
vis[que[0] = que[len - 1]] = true, len = 1;
|
||||
for (int i = 0; i < len; i++)
|
||||
for (int e = adj[que[i]], cnt = 0; e; e = nxt[e])
|
||||
if (!vis[to[e]])
|
||||
A[i] = la[e], B[i] = lb[e], vis[que[len++] = to[e]] = true;
|
||||
for (int i = 0; i < len; i++) pos[que[i]] = i;
|
||||
while (q--) {
|
||||
int u, v, a, b;
|
||||
read(u), read(v), read(a), read(b);
|
||||
int _u = pos[u], _v = pos[v], ma = -inf, mb = -inf;
|
||||
u = _u < _v ? _u : _v;
|
||||
v = _u > _v ? _u : _v;
|
||||
bool ans = false, reachable = true;
|
||||
for (int i = u; i < v && reachable; i++) {
|
||||
if (A[i] > a || B[i] > b) reachable = false;
|
||||
ma = max(ma, A[i]), mb = max(mb, B[i]);
|
||||
if (ma == a && mb == b) ans = true;
|
||||
}
|
||||
if (!reachable) ans = false;
|
||||
if (reachable && !ans)
|
||||
for (int i = u - 1; i >= 0 && !ans; i--) {
|
||||
if (A[i] > a || B[i] > b) break;
|
||||
ma = max(ma, A[i]), mb = max(mb, B[i]);
|
||||
if (ma == a && mb == b) ans = true;
|
||||
}
|
||||
if (reachable && !ans)
|
||||
for (int i = v; i < len && !ans; i++) {
|
||||
if (A[i] > a || B[i] > b) break;
|
||||
ma = max(ma, A[i]), mb = max(mb, B[i]);
|
||||
if (ma == a && mb == b) ans = true;
|
||||
}
|
||||
puts(ans ? "Yes" : "No");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -0,0 +1,160 @@
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <queue>
|
||||
inline void read(int &x)
|
||||
{
|
||||
int ch = x = 0, flag = 1;
|
||||
while (!isdigit(ch = getchar()))
|
||||
if (ch == '-') flag = -1;
|
||||
for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
|
||||
x *= flag;
|
||||
}
|
||||
const int inf = 0x3f3f3f3f, N = int(1e5 + 5), M = N << 1;
|
||||
#define avg(x, y) ((x) + (((y) - (x)) >> 1))
|
||||
#define L(x) ((x) << 1)
|
||||
#define R(x) ((x) << 1 | 1)
|
||||
template <typename T>
|
||||
struct __ext_priority_queue
|
||||
{
|
||||
private:
|
||||
std::priority_queue<T> a, b;
|
||||
|
||||
public:
|
||||
void push(const T &x) { a.push(x); }
|
||||
void pop(const T &x) { b.push(x); }
|
||||
T top()
|
||||
{
|
||||
while (!b.empty() && a.top() == b.top()) a.pop(), b.pop();
|
||||
return a.empty() ? -1 : a.top();
|
||||
}
|
||||
};
|
||||
__ext_priority_queue<int> node[N << 2];
|
||||
void modify(int k, int l, int r, int x, int y, int v, bool t)
|
||||
{
|
||||
if (x <= l && r <= y) return void(t ? node[k].push(v) : node[k].pop(v));
|
||||
int m = avg(l, r);
|
||||
if (x < m) modify(L(k), l, m, x, y, v, t);
|
||||
if (y > m) modify(R(k), m, r, x, y, v, t);
|
||||
}
|
||||
/*
|
||||
void change(int x, int L, int R, int l, int r, int w, bool flag)
|
||||
{
|
||||
if (L == l && R == r)
|
||||
if (flag) t[x].insert(w);
|
||||
else t[x].erase(w);
|
||||
else
|
||||
{
|
||||
int mid = (L + R) >> 1;
|
||||
if (r <= mid) change(x << 1, L, mid, l, r, w, flag);
|
||||
else if (l > mid) change(x << 1 | 1, mid + 1, R, l, r, w, flag);
|
||||
else change(x << 1, L, mid, l, mid, w, flag), change(x << 1 | 1, mid + 1, R, mid + 1, r, w, flag);
|
||||
}
|
||||
}
|
||||
*/
|
||||
int query(int k, int l, int r, int p)
|
||||
{
|
||||
int cur = node[k].top();
|
||||
if (l == r - 1) return cur;
|
||||
int m = avg(l, r);
|
||||
return std::max(cur, p < m ? query(L(k), l, m, p) : query(R(k), m, r, p));
|
||||
}
|
||||
/*
|
||||
void getmax(int x, int l, int r, int k)
|
||||
{
|
||||
ans = max(ans, t[x].top());
|
||||
if (l == r) return;
|
||||
else
|
||||
{
|
||||
int mid = (l + r) >> 1;
|
||||
if (k <= mid)
|
||||
getmax(x << 1, l, mid, k);
|
||||
else
|
||||
getmax(x << 1 | 1, mid + 1, r, k);
|
||||
}
|
||||
}
|
||||
*/
|
||||
int adj[N], nxt[N << 1], to[N << 1], ecnt;
|
||||
inline void addEdge(int f, int t)
|
||||
{
|
||||
ecnt++;
|
||||
nxt[ecnt] = adj[f];
|
||||
adj[f] = ecnt;
|
||||
to[ecnt] = t;
|
||||
}
|
||||
int n, m;
|
||||
int sz[N], fa[N], dep[N], son[N], top[N], idx[N], pos[N];
|
||||
void HLD()
|
||||
{
|
||||
int u, v, len = 0;
|
||||
static int que[N];
|
||||
que[len++] = 1;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
sz[u = que[i]] = 1;
|
||||
for (int e = adj[u]; e; e = nxt[e])
|
||||
if ((v = to[e]) != fa[u])
|
||||
fa[v] = u, dep[v] = dep[u] + 1, que[len++] = v;
|
||||
}
|
||||
for (int i = len - 1; i; i--)
|
||||
{
|
||||
u = que[i], v = fa[u];
|
||||
sz[v] += sz[u];
|
||||
if (sz[u] > sz[son[v]]) son[v] = u;
|
||||
}
|
||||
for (int i = 0, tot = 0; i < len; i++)
|
||||
if (top[u = que[i]] == 0)
|
||||
for (v = u; v; v = son[v])
|
||||
top[idx[pos[v] = tot++] = v] = u;
|
||||
}
|
||||
void work(int u, int v, int w, bool t)
|
||||
{
|
||||
typedef std::pair<int, int> seg;
|
||||
static seg segs[N];
|
||||
int scnt = 0;
|
||||
segs[scnt++] = seg(-1, -1);
|
||||
while (top[u] != top[v])
|
||||
{
|
||||
if (dep[top[u]] < dep[top[v]]) std::swap(u, v);
|
||||
segs[scnt++] = seg(pos[top[u]], pos[u]);
|
||||
u = fa[top[u]];
|
||||
}
|
||||
if (dep[u] > dep[v]) std::swap(u, v);
|
||||
segs[scnt++] = seg(pos[u], pos[v]);
|
||||
segs[scnt] = seg(n, n);
|
||||
std::sort(segs, segs + scnt);
|
||||
for (int i = 0; i <= scnt; i++)
|
||||
if (segs[i].second + 1 < segs[i + 1].first)
|
||||
modify(1, 0, n, segs[i].second + 1, segs[i + 1].first, w, t);
|
||||
}
|
||||
int main()
|
||||
{
|
||||
read(n), read(m);
|
||||
for (int i = 1, u, v; i < n; i++) read(u), read(v), addEdge(u, v), addEdge(v, u);
|
||||
HLD();
|
||||
for (int i = 1; i <= m; i++)
|
||||
{
|
||||
static int Qf[M], Qt[M], Qv[M];
|
||||
int type;
|
||||
read(type);
|
||||
if (type == 0)
|
||||
{
|
||||
read(Qf[i]), read(Qt[i]), read(Qv[i]);
|
||||
work(Qf[i], Qt[i], Qv[i], true);
|
||||
}
|
||||
if (type == 1)
|
||||
{
|
||||
int t;
|
||||
read(t);
|
||||
work(Qf[t], Qt[t], Qv[t], false);
|
||||
}
|
||||
if (type == 2)
|
||||
{
|
||||
int x;
|
||||
read(x);
|
||||
printf("%d\n", query(1, 0, n, pos[x]));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
40/100/30
|
||||
@ -0,0 +1,96 @@
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
inline void read(int &x)
|
||||
{
|
||||
int ch = x = 0, flag = 1;
|
||||
while (!isdigit(ch = getchar()))
|
||||
if (ch == '-') flag = -1;
|
||||
for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
|
||||
x *= flag;
|
||||
}
|
||||
const int N = 100010;
|
||||
int adj[N], nxt[N << 1], to[N << 1], ecnt;
|
||||
inline void addEdge(int f, int t)
|
||||
{
|
||||
ecnt++;
|
||||
nxt[ecnt] = adj[f];
|
||||
adj[f] = ecnt;
|
||||
to[ecnt] = t;
|
||||
}
|
||||
typedef vector<int> vint;
|
||||
typedef vint::iterator vite;
|
||||
vint pattern;
|
||||
int dep[N << 4];
|
||||
vector<pair<vite, vite> > tRanges;
|
||||
void dfs(int u, int fa)
|
||||
{
|
||||
if (dep[u] == -1) dep[u] = dep[fa] + 1;
|
||||
tRanges[u].first = pattern.end();
|
||||
pattern.push_back(u);
|
||||
for (int e = adj[u]; e; e = nxt[e])
|
||||
if (to[e] != fa)
|
||||
dfs(to[e], u), pattern.push_back(u);
|
||||
tRanges[u].second = pattern.end();
|
||||
}
|
||||
vector<int> newTree;
|
||||
int main()
|
||||
{
|
||||
memset(dep, -1, sizeof(dep));
|
||||
int n, m, q;
|
||||
read(n), read(m), read(q);
|
||||
for (int i = 1, u, v; i < n; i++)
|
||||
{
|
||||
read(u), read(v);
|
||||
addEdge(u, v), addEdge(v, u);
|
||||
}
|
||||
pattern.reserve((n << 1) - 1);
|
||||
tRanges.resize((n << 1) - 1);
|
||||
dfs(1, 0);
|
||||
newTree = pattern;
|
||||
while (m--)
|
||||
{
|
||||
int x, t;
|
||||
read(x), read(t);
|
||||
vint tmp = vint(tRanges[x].first, tRanges[x].second), toSort = tmp;
|
||||
sort(toSort.begin(), toSort.end());
|
||||
vite fin = unique(toSort.begin(), toSort.end());
|
||||
int sz = (newTree.size() + 1) >> 1, delteDep = dep[t] - dep[x] + 1;
|
||||
for (vite ite = tmp.begin(); ite != tmp.end(); ++ite)
|
||||
{
|
||||
int newVal = lower_bound(toSort.begin(), fin, *ite) - toSort.begin() + sz + 1;
|
||||
dep[newVal] = dep[*ite] + delteDep;
|
||||
*ite = newVal;
|
||||
}
|
||||
vite insPos = newTree.end() - 1;
|
||||
while (*insPos != t) --insPos;
|
||||
tmp.push_back(t);
|
||||
newTree.insert(insPos + 1, tmp.begin(), tmp.end());
|
||||
}
|
||||
static int RMQ[N << 4][20];
|
||||
int sz = newTree.size();
|
||||
for (int i = 0; i < sz; i++) RMQ[i][0] = dep[newTree[i]];
|
||||
for (int j = 1; (1 << j) <= sz; j++)
|
||||
for (int i = 0; i < sz; i++)
|
||||
RMQ[i][j] = min(RMQ[i][j - 1], RMQ[i + (1 << (j - 1))][j - 1]);
|
||||
tRanges.resize(0);
|
||||
static int P[N << 4];
|
||||
memset(P, -1, sizeof(P));
|
||||
for (vite ite = newTree.begin(); ite != newTree.end(); ++ite)
|
||||
if (P[*ite] == -1) P[*ite] = ite - newTree.begin();
|
||||
while (q--)
|
||||
{
|
||||
int f, t;
|
||||
read(f), read(t);
|
||||
int sumDep = dep[f] + dep[t];
|
||||
f = P[f], t = P[t];
|
||||
if (f > t) swap(f, t);
|
||||
int k = log2(t - f + 1);
|
||||
printf("%d\n", sumDep - (min(RMQ[f][k], RMQ[t - (1 << k) + 1][k]) << 1));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in new issue