菜鸡刷题记录

[题号:题解]


1008:简单排列组合

 #include <bits/stdc++.h>
using namespace std; #define ll long long
const ll MOD = (ll)1e5 + ;
ll n, m; ll qmod(ll base, ll n)
{
ll res = ;
while (n)
{
if (n & ) res = res * base % MOD;
base = base * base % MOD;
n >>= ;
}
return res;
} int main()
{
while (scanf("%lld%lld", &m, &n) != EOF)
printf("%lld\n", (qmod(m, n) - (m % MOD * qmod(m - , n - ) % MOD) + MOD) % MOD);
return ;
}

1012:BIT维护后缀最大

 #include <bits/stdc++.h>
using namespace std; #define N 1000010
#define ll long long
int m, n; ll D; struct BIT
{
ll a[N];
void Init() { memset(a, , sizeof a); }
void update(int x, ll val)
{
for (; x; x -= x & -x)
a[x] = max(a[x], val);
}
ll query(int x)
{
ll res = ;
for (; x <= n; x += x & -x)
res = max(res, a[x]);
return res;
}
}bit; void Run()
{
scanf("%d%lld", &m, &D);
bit.Init();
char op; ll x, lastans = ; n = ;
for (int i = ; i <= m; ++i)
{
scanf(" %c%lld", &op, &x);
if (op == 'Q') printf("%lld\n", lastans = bit.query(n - x + ));
else bit.update(++n, (x + lastans) % D);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ; }

1051:Tarjan缩点

 #include <bits/stdc++.h>
using namespace std; #define pii pair <int, int>
#define N 10010 int n, m;
map <pii, bool> mp;
vector <int> G[N];
int Low[N], DFN[N], Stack[N], Belong[N], sze[N], degree[N], cnt, sec, top;
bool Instack[N]; void Tarjan(int u)
{
Low[u] = DFN[u] = ++cnt;
Stack[top++] = u;
Instack[u] = ;
for (int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i];
if (!DFN[v])
{
Tarjan(v);
Low[u] = min(Low[u], Low[v]);
}
else if (Instack[v]) Low[u] = min(Low[u], DFN[v]);
}
if (DFN[u] == Low[u])
{
++sec; int v;
do
{
v = Stack[--top];
Instack[v] = ;
Belong[v] = sec;
++sze[sec];
} while (v != u);
}
} int Run()
{
for (int i = ; i <= n; ++i) if (!DFN[i])
Tarjan(i);
for (int u = ; u <= n; ++u)
{
for (int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i];
if (Belong[v] != Belong[u])
++degree[Belong[u]];
}
}
int flag = ;
for (int i = ; i <= sec; ++i) if (!degree[i]) ++flag;
if (flag > ) return ;
for (int i = ; i <= sec; ++i) if (!degree[i])
return sze[i];
return ;
} int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = ; i <= n; ++i) G[i].clear();
mp.clear(); cnt = ; sec = ; top = ;
memset(sze, , sizeof sze);
memset(degree, , sizeof degree);
for (int i = , u, v; i <= m; ++i)
{
scanf("%d%d", &u, &v);
if(mp.find(pii(u, v)) != mp.end()) continue;
G[u].push_back(v);
mp[pii(u, v)] = ;
}
printf("%d\n", Run());
}
return ;
}

1086:树分块

 #include <bits/stdc++.h>
using namespace std; #define N 1010 int n, b;
vector <int> G[N];
stack <int> sta;
int Belong[N], sze[N], cap[N], cnt; void DFS(int u, int fa)
{
sze[u] = ;
sta.push(u);
for (int i = , v, len = G[u].size(); i < len; ++i) if ((v = G[u][i]) != fa)
{
DFS(v, u);
sze[u] += sze[v];
if (sze[u] >= b)
{
sze[u] = ;
cap[++cnt] = u;
while (!sta.empty() && sta.top() != u) { Belong[sta.top()] = cnt; sta.pop(); }
}
}
++sze[u];
} void DFS2(int u, int fa, int sp)
{
Belong[u] ? sp = Belong[u] : Belong[u] = sp;
for (int i = , v, len = G[u].size(); i < len; ++i) if ((v = G[u][i]) != fa)
DFS2(v, u, sp);
} void Run()
{
while (scanf("%d%d", &n, &b) != EOF)
{
if (n < b) { puts(""); continue; }
for (int i = ; i <= n; ++i) G[i].clear();
while (!sta.empty()) sta.pop();
cnt = ;
memset(Belong, , sizeof Belong);
for (int i = , u, v; i < n; ++i)
{
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
DFS(, ); DFS2(, , cnt);
if (!cnt) cap[cnt = ] = ;
printf("%d\n", cnt);
for (int i = ; i <= n; ++i) printf("%d%c", Belong[i], " \n"[i == n]);
for (int i = ; i <= cnt; ++i) printf("%d%c", cap[i], " \n"[i == cnt]);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ; }

1216:模拟+优先队列,主要不要暴力枚举时间

 #include <bits/stdc++.h>
using namespace std; #define N 1501000
#define ll long long
struct node
{
int id, pri; ll arrive, time;
int scan() { return scanf("%d%lld%lld%d", &id, &arrive, &time, &pri); }
void output(ll now) { printf("%d %lld\n", id, now); }
bool operator < (const node &r) const
{
return pri < r.pri || (pri == r.pri && id > r.id);
}
}arr[N]; priority_queue <node> q; int main()
{
int n;
for (n = ; ; ++n) if (arr[n].scan() == EOF) break; --n;
while (!q.empty()) q.pop();
ll t = ;
for (int i = ; i <= n; ++i)
{
if (q.empty())
{
q.push(arr[i]);
t = max(t, arr[i].arrive);
}
else
{
node tmp = q.top();
while (t + tmp.time <= arr[i].arrive)
{
t += tmp.time;
q.pop();
tmp.output(t);
if (q.empty()) break;
tmp = q.top();
}
if (t < arr[i].arrive && !q.empty())
{
ll gap = arr[i].arrive - t;
tmp = q.top(); q.pop();
tmp.time -= gap;
q.push(tmp);
t = arr[i].arrive;
}
q.push(arr[i]);
t = max(t, arr[i].arrive);
}
}
while (!q.empty())
{
node tmp = q.top(); q.pop();
t += tmp.time;
tmp.output(t);
}
return ;
}

1635:差分+坑 有重复

 #include <bits/stdc++.h>
using namespace std; #define N 10100
#define pii pair <int, int>
int n, i, h, q;
int ans[N];
map <pii, bool> mp; int main()
{
while (scanf("%d%d%d%d", &n, &i, &h, &q) != EOF)
{
memset(ans, , sizeof ans);
mp.clear();
for (int i = , l, r; i <= q; ++i)
{
scanf("%d%d", &l, &r);
if (l > r) swap(l, r);
if (mp.find(pii(l, r)) != mp.end()) continue;
mp[pii(l, r)] = ;
--ans[l + ]; ++ans[r];
}
for (int i = ; i <= n; ++i) ans[i] += ans[i - ];
for (int i = ; i <= n; ++i) printf("%d\n", h + ans[i]);
}
return ;
}

1935:排序一维,树状数组一维

 #include <bits/stdc++.h>
using namespace std; #define N 3000010 int n, q, m;
int ans[N], brr[N];
struct node
{
// 0 insert
// 1 add
// 2 sub
int op, x, y, id;
node() {}
node(int op, int x, int y, int id) : op(op), x(x), y(y), id(id) {}
bool operator < (const node &r) const
{
return x == r.x ? id < r.id : x < r.x;
}
}arr[N]; struct BIT
{
int a[N]; void Init()
{
memset(a, , sizeof a);
} void update(int x, int val)
{
while (x <= m)
{
a[x] += val;
x += x & -x;
}
} int query(int x)
{
int res = ;
while (x)
{
res += a[x];
x -= x & -x;
}
return res;
}
}bit; void Hash()
{
sort(brr + , brr + + m);
int tmp = unique(brr + , brr + + m) - brr - ;
for (int i = ; i <= m; ++i)
arr[i].y = lower_bound(brr + , brr + + tmp, arr[i].y) - brr;
} void Run()
{
while (scanf("%d%d", &n, &q) != EOF)
{
m = n;
for (int i = , x, y; i <= n; ++i)
{
scanf("%d%d", &x, &y);
arr[i] = node(, x, y, );
brr[i] = y;
}
for (int i = , x[], y[]; i <= q; ++i)
{
for (int j = ; j < ; ++j) scanf("%d%d", x + j, y + j);
arr[++m] = node(, x[], y[], i); brr[m] = y[];
arr[++m] = node(, x[] - , y[] - , i); brr[m] = y[] - ;
arr[++m] = node(-, x[], y[] - , i); brr[m] = y[] - ;
arr[++m] = node(-, x[] - , y[], i); brr[m] = y[];
}
Hash();
sort(arr + , arr + + m);
for (int i = ; i <= m; ++i)
{
if (arr[i].id == ) bit.update(arr[i].y, );
else
ans[arr[i].id] += bit.query(arr[i].y) * arr[i].op;
}
for (int i = ; i <= q; ++i) printf("%d\n", ans[i]);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

2014:虚树+DP

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define INF 0x3f3f3f3f3f3f3f3f
#define N 1000010
int n, q, k, a[N]; struct Graph
{
struct node
{
int to, nx;
node() {}
node(int to, int nx) : to(to), nx(nx) {}
}a[N << ];
int head[N], pos;
void init() { memset(head, , sizeof head); pos = ; }
void add(int u, int v)
{
a[++pos] = node(v, head[u]); head[u] = pos;
a[++pos] = node(u, head[v]); head[v] = pos;
}
}g[];
#define erp(id, u) for (int it = g[id].head[u], v = g[id].a[it].to; it; it = g[id].a[it].nx, v = g[id].a[it].to) int fa[N], son[N], top[N], p[N], cnt; ll deep[N], sze[N];
void DFS(int u)
{
sze[u] = ;
erp(, u) if (v != fa[u])
{
fa[v] = u;
deep[v] = deep[u] + ;
DFS(v); sze[u] += sze[v];
if (!son[u] || sze[v] > sze[son[u]]) son[u] = v;
}
} void getpos(int u, int sp)
{
top[u] = sp;
p[u] = ++cnt;
if (!son[u]) return;
getpos(son[u], sp);
erp(, u) if (v != fa[u] && v != son[u])
getpos(v, v);
} int querylca(int u, int v)
{
while (top[u] != top[v])
{
if (deep[top[u]] < deep[top[v]]) swap(u, v);
u = fa[top[u]];
}
if (deep[u] > deep[v]) swap(u, v);
return u;
} ll Max[N], Min[N], sum[N], res_Max, res_Min, res_sum; int vis[N];
void dp(int u, int fa)
{
Max[u] = ; Min[u] = INF; sum[u] = ;
sze[u] = vis[u];
erp(, u) if (v != fa)
dp(v, u), sze[u] += sze[v];
if (vis[u]) Max[u] = Min[u] = sum[u] = deep[u];
erp(, u) if (v != fa)
{
sum[u] += sum[v];
res_sum += (sum[v] - deep[u] * sze[v]) * (sze[u] - sze[v]);
if (Max[u]) res_Max = max(res_Max, Max[u] + Max[v] - * deep[u]);
Max[u] = max(Max[u], Max[v]);
if (Min[v] != INF) res_Min = min(res_Min, Min[u] + Min[v] - * deep[u]);
Min[u] = min(Min[u], Min[v]);
}
vis[u] = ; g[].head[u] = ;
} bool cmp(int a, int b) { return p[a] < p[b]; } void init()
{
g[].init(); g[].init(); cnt = ;
memset(son, , sizeof son);
} int stktop, stk[N];
void Run()
{
while (scanf("%d", &n) != EOF)
{
init();
for (int i = , u, v; i < n; ++i)
{
scanf("%d%d", &u, &v);
g[].add(u, v);
} deep[] = ; DFS(); getpos(, );
scanf("%d", &q);
for (int qq = ; qq <= q; ++qq)
{
scanf("%d", &k);
for (int i = ; i <= k; ++i) scanf("%d", a + i);
sort(a + , a + + k, cmp);
for (int i = ; i <= k; ++i) vis[a[i]] = ;
stk[stktop = ] = ; g[].pos = ;
for (int i = ; i <= k; ++i)
{
int lca = querylca(stk[stktop], a[i]);
while (deep[lca] < deep[stk[stktop]])
{
if (deep[stk[stktop - ]] <= deep[lca])
{
int last = stk[stktop--];
if (stk[stktop] != lca) stk[++stktop] = lca;
g[].add(last, lca);
break;
}
g[].add(stk[stktop - ], stk[stktop]), --stktop;
}
if (stk[stktop] != a[i]) stk[++stktop] = a[i];
}
while (stktop > ) g[].add(stk[stktop - ], stk[stktop]), --stktop;
res_Max = , res_Min = INF; res_sum = ;
dp(, );
printf("%lld %lld %lld\n", res_sum, res_Min, res_Max);
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

2056:特判+不要用iostream

 #include <cstdio>
#define ull unsigned long long
int t, a[];
ull res; int main()
{
scanf("%d", &t);
while (t--)
{
for (int i = ; i <= ; ++i) scanf("%d", a + i);
scanf("%llu", &res);
for (int i = ; i <= ; ++i) res += 1ll << a[i];
if (res == ) res = -;
if (res != -) printf("%llu\n", res);
else
{
printf("%llu", res / );
puts("");
}
}
return ;
}

2120:带修改莫队

 #include <bits/stdc++.h>
using namespace std; #define N 100010
#define block 400 int n, q, cnt_que, cnt_op;
int arr[N], brr[N], ans[N], cnt[N * ], res; struct QUE
{
int l, r, id, ti;
void scan(int id, int ti)
{
this->id = id;
this->ti = ti;
scanf("%d%d", &l, &r);
}
bool operator < (const QUE &r) const
{
int posl = l / block, posr = r.l / block;
return posl == posr ? this->r < r.r : posl < posr;
}
}que[N]; struct OP
{
int pre, v, id;
void scan()
{
scanf("%d%d", &id, &v);
pre = brr[id];
brr[id] = v;
}
}op[N]; void update(int x, int val)
{
if (val == -)
{
if (cnt[arr[x]] == ) --res;
--cnt[arr[x]];
}
else
{
++cnt[arr[x]];
if (cnt[arr[x]] == ) ++res;
}
} void change(int ti, int vis, int l, int r)
{
int pos = op[ti].id;
int v = vis ? op[ti].v : op[ti].pre;
if (pos >= l && pos <= r)
{
update(pos, -);
arr[pos] = v;
update(pos, );
}
else arr[pos] = v;
} void Run()
{
while (scanf("%d%d", &n, &q) != EOF)
{
cnt_que = cnt_op = res = ;
for (int i = ; i <= n; ++i) scanf("%d", arr + i);
for (int i = ; i <= n; ++i) brr[i] = arr[i];
char opp;
for (int i = ; i <= q; ++i)
{
scanf(" %c", &opp);
if (opp == 'Q') que[++cnt_que].scan(cnt_que, cnt_op);
else op[++cnt_op].scan();
}
sort(que + , que + + cnt_que);
for (int i = , l = , r = , ti = ; i <= cnt_que; ++i)
{
for (; ti < que[i].ti; ++ti) change(ti + , , l, r);
for (; ti > que[i].ti; --ti) change(ti, , l, r);
for (; r < que[i].r; ++r) update(r + , );
for (; r > que[i].r; --r) update(r, -);
for (; l < que[i].l; ++l) update(l, -);
for (; l > que[i].l; --l) update(l - , );
ans[que[i].id] = res;
}
for (int i = ; i <= cnt_que; ++i) printf("%d\n", ans[i]);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

2141:分块+树状数组

 #include <bits/stdc++.h>
using namespace std; #define N 20010
#define block 200 int n, m, q;
int arr[N], brr[N], pos[N], num[N]; struct BIT
{
int a[N];
void update(int x, int val)
{
while (x <= n)
{
a[x] += val;
x += x & -x;
}
} int query(int x)
{
int res = ;
while (x)
{
res += a[x];
x -= x & -x;
}
return res;
} }bit[block]; int query(int x)
{
int res = ;
for (int i = ; i < pos[x]; ++i)
res += num[i] - bit[i].query(arr[x]);
for (int i = x - ; i >= && pos[i] == pos[x]; --i) if (arr[i] > arr[x])
++res;
for (int i = x + ; i <= n && pos[i] == pos[x]; ++i) if (arr[i] < arr[x])
++res;
for (int i = pos[x] + ; i <= pos[n]; ++i)
res += bit[i].query(arr[x] - );
return res;
} void Run()
{
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%d", arr + i);
for (int i = ; i <= n; ++i) brr[i] = arr[i];
sort(brr + , brr + + n);
m = unique(brr + , brr + + n) - brr - ;
for (int i = ; i <= n; ++i) arr[i] = lower_bound(brr + , brr + + m, arr[i]) - brr;
for (int i = ; i <= n; ++i) pos[i] = (i - ) / block + , ++num[pos[i]];
int res = ;
for (int i = ; i <= n; ++i)
{
bit[].update(arr[i], );
res += i - bit[].query(arr[i]);
}
printf("%d\n", res);
for (int i = ; i <= n; ++i) bit[pos[i]].update(arr[i], );
scanf("%d", &q);
for (int i = , l, r; i <= q; ++i)
{
scanf("%d%d", &l, &r);
if (l > r) swap(l, r);
res -= query(l);
res -= query(r);
if (arr[l] > arr[r]) ++res;
bit[pos[l]].update(arr[l], -);
bit[pos[r]].update(arr[r], -);
swap(arr[l], arr[r]);
bit[pos[l]].update(arr[l], );
bit[pos[r]].update(arr[r], );
res += query(l);
res += query(r);
if (arr[l] > arr[r]) --res;
printf("%d\n", res);
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

2157:树剖+线段树

 #include <bits/stdc++.h>
using namespace std; #define N 100010
#define INF 0x3f3f3f3f
int n, q;
struct Edge { int u, v, w; Edge() {} Edge(int u, int v, int w) : u(u), v(v), w(w) {}}edge[N];
vector <int> G[N];
int p[N], fp[N], sze[N], son[N], fa[N], deep[N], top[N], cnt; void DFS(int u)
{
sze[u] = ;
for (int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i];
if (v == fa[u]) continue;
fa[v] = u;
deep[v] = deep[u] + ;
DFS(v); sze[u] += sze[v];
if (!son[u] || sze[v] > sze[son[u]]) son[u] = v;
}
} void getpos(int u, int sp)
{
top[u] = sp;
p[u] = ++cnt;
fp[cnt] = u;
if (!son[u]) return;
getpos(son[u], sp);
for (int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i];
if (v == fa[u] || v == son[u]) continue;
getpos(v, v);
}
} struct SEG
{
struct node
{
int sum, Max, Min, lazy;
void init()
{
sum = ;
Max = -INF;
Min = INF;
lazy = ;
}
node operator + (const node &r) const
{
node res; res.init();
res.sum = sum + r.sum;
res.Max = max(Max, r.Max);
res.Min = min(Min, r.Min);
return res;
}
void change()
{
sum *= -;
Max *= -;
Min *= -;
lazy *= -;
swap(Max, Min);
}
}a[N << ], res;
void build(int id, int l, int r)
{
a[id].init();
if (l == r) return;
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
}
void pushdown(int id)
{
if (a[id].lazy != )
{
a[id].lazy = ;
a[id << ].change();
a[id << | ].change();
}
}
void update(int id, int l, int r, int pos, int val)
{
if (l == r)
{
a[id].sum = a[id].Max = a[id].Min = val;
return;
}
pushdown(id);
int mid = (l + r) >> ;
if (pos <= mid) update(id << , l, mid, pos, val);
else update(id << | , mid + , r, pos, val);
a[id] = a[id << ] + a[id << | ];
}
void update(int id, int l, int r, int ql, int qr, int val)
{
if (l >= ql && r <= qr)
{
a[id].change();
return;
}
pushdown(id);
int mid = (l + r) >> ;
if (ql <= mid) update(id << , l, mid, ql, qr, val);
if (qr > mid) update(id << | , mid + , r, ql, qr, val);
a[id] = a[id << ] + a[id << | ];
}
void query(int id, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr)
{
res = res + a[id];
return;
}
pushdown(id);
int mid = (l + r) >> ;
if (ql <= mid) query(id << , l, mid, ql, qr);
if (qr > mid) query(id << | , mid + , r, ql, qr);
a[id] = a[id << ] + a[id << | ];
}
}seg; void update(int u, int v)
{
while (top[u] != top[v])
{
if (deep[top[u]] < deep[top[v]])
swap(u, v);
seg.update(, , n, p[top[u]], p[u], -);
u = fa[top[u]];
}
if (u == v) return;
if (deep[u] > deep[v]) swap(u, v);
seg.update(, , n, p[son[u]], p[v], -);
} void query(int u, int v)
{
while (top[u] != top[v])
{
if (deep[top[u]] < deep[top[v]])
swap(u, v);
seg.query(, , n, p[top[u]], p[u]);
u = fa[top[u]];
}
if (u == v) return;
if (deep[u] > deep[v]) swap(u, v);
seg.query(, , n, p[son[u]], p[v]);
} int main()
{
while (scanf("%d", &n) != EOF)
{
cnt = ;
for (int i = , u, v, w; i < n; ++i)
{
scanf("%d%d%d", &u, &v, &w); ++u, ++v;
edge[i] = Edge(u, v, w);
G[u].push_back(v);
G[v].push_back(u);
}
DFS();
getpos(, );
seg.build(, , n);
for (int i = ; i < n; ++i)
{
if (edge[i].u != fa[edge[i].v]) swap(edge[i].u, edge[i].v);
seg.update(, , n, p[edge[i].v], edge[i].w);
}
char op[]; int u, v;
scanf("%d", &q);
for (int i = ; i <= q; ++i)
{
scanf("%s%d%d", op, &u, &v); ++u, ++v;
if (op[] == 'N') update(u, v);
else if (op[] == 'C') seg.update(, , n, p[edge[u - ].v], v - );
else
{
seg.res.init();
query(u, v);
if (op[] == 'S') printf("%d\n", seg.res.sum);
else if (op[] == 'I') printf("%d\n", seg.res.Min);
else printf("%d\n", seg.res.Max);
}
}
}
return ;
}

2286:虚数+树形DP

 #include <bits/stdc++.h>
using namespace std; #define INFLL 0x3f3f3f3f3f3f3f3f
#define ll long long
#define N 250010
int n, q; struct Edge
{
struct node
{
int to, nx, w;
node() {}
node(int to, int nx, int w) : to(to), nx(nx), w(w) {}
}a[N << ];
int head[N], pos;
void add(int u, int v, int w)
{
a[++pos] = node(v, head[u], w); head[u] = pos;
a[++pos] = node(u, head[v], w); head[v] = pos;
}
}g[];
#define erp(id, u) for (int it = g[id].head[u], v = g[id].a[it].to; it; it = g[id].a[it].nx, v = g[id].a[it].to) int p[N], cnt, deep[N], fa[N], sze[N], son[N], top[N], vis[N]; ll val[N];
void DFS(int u)
{
sze[u] = ;
erp(, u) if (v != fa[u])
{
fa[v] = u;
deep[v] = deep[u] + ;
val[v] = min(val[u], (ll)g[].a[it].w);
DFS(v); sze[u] += sze[v];
if (!son[u] || sze[v] > sze[son[u]]) son[u] = v;
}
} void getpos(int u, int sp)
{
top[u] = sp;
p[u] = ++cnt;
if (!son[u]) return;
getpos(son[u], sp);
erp(, u) if (v != fa[u] && v != son[u])
getpos(v, v);
} int querylca(int u, int v)
{
while (top[u] != top[v])
{
if (deep[top[u]] < deep[top[v]]) swap(u, v);
u = fa[top[u]];
}
if (deep[u] > deep[v]) swap(u, v);
return u;
} ll dp(int u, int fa)
{
ll tmp = ;
erp(, u) if (v != fa) tmp += dp(v, u);
g[].head[u] = ;
if (tmp == || vis[u]) return vis[u] = , val[u];
return min(val[u], tmp);
} bool cmp(int a, int b) { return p[a] < p[b]; } int a[N], stk[N], stktop;
void Run()
{
while (scanf("%d", &n) != EOF)
{
val[] = INFLL;
for (int i = , u, v, w; i < n; ++i)
{
scanf("%d%d%d", &u, &v, &w);
g[].add(u, v, w);
}DFS(); getpos(, );
scanf("%d", &q);
for (int qq = , k; qq <= q; ++qq)
{
scanf("%d", &k);
for (int i = ; i <= k; ++i) scanf("%d", a + i), vis[a[i]] = ;
sort(a + , a + + k, cmp);
stk[stktop = ] = ; g[].pos = ;
for (int i = ; i <= k; ++i)
{
int lca = querylca(a[i], stk[stktop]);
while (deep[lca] < deep[stk[stktop]])
{
if (deep[stk[stktop - ]] <= deep[lca])
{
int last = stk[stktop--];
if (stk[stktop] != lca) stk[++stktop] = lca;
g[].add(last, lca, );
break;
}
g[].add(stk[stktop], stk[stktop - ], ), --stktop;
}
if (stk[stktop] != a[i]) stk[++stktop] = a[i];
}
while (stktop > ) g[].add(stk[stktop], stk[stktop - ], ), --stktop;
printf("%lld\n", dp(, ));
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

2654:二分+Kruskal()

 #include <bits/stdc++.h>
using namespace std; #define N 100010
struct node
{
int u, v, clo, base, w;
void scan()
{
scanf("%d%d%d%d", &u, &v, &base, &clo);
++u, ++v;
if (clo == ) w = base;
}
bool operator < (const node &r) const
{
return w < r.w || (w == r.w && clo < r.clo);
}
}edge[N];
int n, m, need;
int pre[N];
int find(int x) { return pre[x] == ? x : pre[x] = find(pre[x]); } #define pii pair <int, int>
pii Kruskal(int add)
{
memset(pre, , sizeof pre);
for (int i = ; i <= m; ++i) if (edge[i].clo == ) edge[i].w = add + edge[i].base;
sort(edge + , edge + + m);
int cnt = , cnt_white = ;
int res = ;
for (int i = ; i <= m; ++i)
{
int u = edge[i].u, v = edge[i].v;
int fu = find(u), fv = find(v);
if (fu == fv) continue;
++cnt; if (edge[i].clo == ) ++cnt_white;
res += edge[i].w;
pre[fu] = fv;
if (cnt == n) break;
}
return pii(res, cnt_white);
} int main()
{
while (scanf("%d%d%d", &n, &m, &need) != EOF)
{
for (int i = ; i <= m; ++i) edge[i].scan();
int l = -, r = , res = ;
while (r - l >= )
{
int mid = (l + r) >> ;
pii tmp = Kruskal(mid);
if (tmp.second >= need) res = tmp.first - mid * need, l = mid + ;
else r = mid - ;
}
printf("%d\n", res);
}
return ;
}

2724:$F[i][j] 表示 第i块到第j块的众数是什么,cntblock[i][j]表示前i块中j这个数出现几次,然后分块维护即可$

 #include <bits/stdc++.h>
using namespace std; #define N 100010
#define block 650
#define pii pair <int, int>
int n, m, q;
int arr[N], brr[N], cnt[N];
int cntblock[block][N], sze;
pii f[block][block]; void Hash()
{
for (int i = ; i <= n; ++i) brr[i] = arr[i];
sort(brr + , brr + + n);
m = unique(brr + , brr + + n) - brr - ;
for (int i = ; i <= n; ++i) arr[i] = lower_bound(brr + , brr + + m, arr[i]) - brr;
} void Init()
{
memset(cntblock, , sizeof cntblock);
memset(f, , sizeof f);
memset(cnt, , sizeof cnt);
} void clean(int l, int r)
{
for (int i = l; i <= r; ++i)
cnt[arr[i]] = ;
} void Run()
{
while (scanf("%d%d", &n, &q) != EOF)
{
Init(); sze = (n - ) / block + ;
for (int i = ; i <= n; ++i) scanf("%d", arr + i); Hash();
for (int i = ; i <= n; ++i)
{
int now = (i - ) / block + ;
if (i != && (i - ) / block + != now)
for (int j = ; j <= m; ++j)
cntblock[now][j] = cntblock[now - ][j];
++cntblock[now][arr[i]];
}
for (int i = ; i <= sze; ++i)
{
for (int j = i; j <= sze; ++j)
{
f[i][j] = f[i][j - ];
int l = (j - ) * block + , r = j * block;
for (int k = l; k <= r; ++k)
{
int num = arr[k];
if (!cnt[num])
cnt[num] += cntblock[j - ][num] - cntblock[i - ][num];
++cnt[num];
if (cnt[num] > f[i][j].first || cnt[num] == f[i][j].first && brr[num] < f[i][j].second)
f[i][j] = pii(cnt[num], brr[num]);
}
clean(l, r);
}
}
int ans = ;
for (int i = , l, r; i <= q; ++i)
{
scanf("%d%d", &l, &r);
l = (l + ans - ) % n + ;
r = (r + ans - ) % n + ;
if (l > r) swap(l, r);
int posl = (l - ) / block + , posr = (r - ) / block + ;
pii res = pii(, );
if (posl == posr)
{
for (int j = l; j <= r; ++j)
{
int num = arr[j];
++cnt[num];
if (cnt[num] > res.first || cnt[num] == res.first && brr[num] < res.second)
res = pii(cnt[num], brr[num]);
}
clean(l, r);
}
else
{
res = f[posl + ][posr - ];
for (int j = l; j <= posl * block; ++j)
{
int num = arr[j];
if (!cnt[num]) cnt[num] += cntblock[posr - ][num] - cntblock[posl][num];
++cnt[num];
if (cnt[num] > res.first || cnt[num] == res.first && brr[num] < res.second)
res = pii(cnt[num], brr[num]);
}
for (int j = (posr - ) * block + ; j <= r; ++j)
{
int num = arr[j];
if (!cnt[num]) cnt[num] += cntblock[posr - ][num] - cntblock[posl][num];
++cnt[num];
if (cnt[num] > res.first || cnt[num] == res.first && brr[num] < res.second)
res = pii(cnt[num], brr[num]);
}
clean(l, posl * block);
clean((posr - ) * block + , r);
}
printf("%d\n", res.second);
ans = res.second;
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

2729:先排男生和老师,老师相邻和不相邻,相邻的话需要插入一个女生

 import java.io.BufferedInputStream;
import java.util.Scanner;
import java.math.*; public class Main { static BigInteger fac[] = new BigInteger[4100];
public static void init()
{
fac[0] = BigInteger.ONE;
for (int i = 1; i < 4100; ++i)
fac[i] = fac[i - 1].multiply(BigInteger.valueOf(i));
} public static BigInteger C(int n, int m)
{
if (n < m || n < 0 || m < 0) return BigInteger.ZERO;
return fac[n].divide(fac[m]).divide(fac[n - m]);
} public static void main(String[] args)
{
init();
Scanner in = new Scanner(new BufferedInputStream(System.in));
int n, m;
while (in.hasNext())
{
n = in.nextInt();
m = in.nextInt();
BigInteger a, b;
a = BigInteger.valueOf(2).multiply(fac[n + 1]).multiply(fac[m]).multiply(C(n + 2, m - 1));
b = BigInteger.valueOf(2).multiply(fac[n]).multiply(fac[m]).multiply(C(n + 1, 2)).multiply(C(n + 3, m));
System.out.println(a.add(b));
}
in.close();
}
}

2738:整体二分

 #include <bits/stdc++.h>
using namespace std; #define N 510
#define M 60010
#define INF 0x3f3f3f3f
int n, q, m;
struct node
{
int x, y, v;
void scan(int x, int y)
{
this->x = x; this->y = y;
scanf("%d", &v);
}
bool operator < (const node &r) const { return v < r.v; }
}arr[N * N]; struct BIT
{
int a[N][N];
void Init() { memset(a, , sizeof a); }
void update(int x, int y, int val)
{
for (int i = x; i <= n; i += i & -i)
for (int j = y; j <= n; j += j & -j)
a[i][j] += val;
}
int query(int x, int y)
{
int res = ;
for (int i = x; i; i -= i & -i)
for (int j = y; j; j -= j & -j)
res += a[i][j];
return res;
}
int query(int x[], int y[])
{
int res = ;
res += query(x[] - , y[] - );
res += query(x[], y[]);
res -= query(x[] - , y[]);
res -= query(x[], y[] - );
return res;
}
}bit; struct qnode
{
int x[], y[], k, id;
void scan(int id)
{
this->id = id;
for (int i = ; i < ; ++i)
scanf("%d%d", x + i, y + i);
scanf("%d", &k);
}
}que[M], ql[M], qr[M]; int ans[M]; void CDQ(int L, int R, int l, int r)
{
if (L > R) return;
if (l == r)
{
for (int i = L; i <= R; ++i)
ans[que[i].id] = arr[l].v;
return;
}
int mid = (l + r) >> ;
for (int i = l; i <= mid; ++i) bit.update(arr[i].x, arr[i].y, );
int posl = , posr = ;
for (int i = L; i <= R; ++i)
{
int sze = bit.query(que[i].x, que[i].y);
if (sze < que[i].k)
{
que[i].k -= sze;
qr[++posr] = que[i];
}
else
ql[++posl] = que[i];
}
for (int i = ; i <= posl; ++i) que[L + i - ] = ql[i];
for (int i = ; i <= posr; ++i) que[L + posl + i - ] = qr[i];
for (int i = l; i <= mid; ++i) bit.update(arr[i].x, arr[i].y, -);
CDQ(L, L + posl - , l, mid);
CDQ(L + posl, R, mid + , r);
} int main()
{
while (scanf("%d%d", &n, &q) != EOF)
{
m = ; bit.Init();
for (int i = ; i <= n; ++i) for (int j = ; j <= n; ++j) arr[++m].scan(i, j);
sort(arr + , arr + + m);
for (int i = ; i <= q; ++i) que[i].scan(i);
CDQ(, q, , m);
for (int i = ; i <= q; ++i) printf("%d\n", ans[i]);
}
return ;
}

2750:$f[u] 表示st -> u的路径数,g[v] 表示 v所能到达的点数  那么一条边<u, v> 提供的贡献就是 f[u] \cdot g[v]$

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 5010
#define INF 0x3f3f3f3f
const ll MOD = (ll)1e9 + ;
int n, m; ll ans[N]; struct Graph
{
struct node
{
int to, nx, w, id;
node() {}
node(int to, int nx, int w, int id) : to(to), nx(nx), w(w), id(id) {}
}a[N << ]; int head[N], pos;
void init()
{
memset(head, -, sizeof head);
pos = ;
}
void add(int u, int v, int w, int id)
{
a[++pos] = node(v, head[u], w, id); head[u] = pos;
}
}G[];
#define erp(G, u) for (int it = G.head[u], v = G.a[it].to, w = G.a[it].w, id = G.a[it].id; ~it; it = G.a[it].nx, v = G.a[it].to, w = G.a[it].w, id = G.a[it].id) namespace Dijkstra
{
struct node
{
int to, w;
node() {}
node(int to, int w) : to(to), w(w) {}
bool operator < (const node &r) const { return w > r.w; }
};
int dist[N]; bool used[N];
void work(int st)
{
for (int i = ; i <= n; ++i) dist[i] = INF, used[i] = false;
priority_queue <node> q; q.push(node(st, )); dist[st] = ;
while (!q.empty())
{
int u = q.top().to; q.pop();
erp(G[], u) if (!used[v] && dist[v] > dist[u] + w)
{
dist[v] = dist[u] + w;
q.push(node(v, w));
}
}
}
} int f[N], g[N], in[N];
void Topo(int p, int *x)
{
G[].init();
for (int i = ; i <= n; ++i) x[i] = p, in[i] = ;
for (int u = ; u <= n; ++u) if (Dijkstra::dist[u] != INF)
{
erp(G[], u) if (Dijkstra::dist[u] + w <= Dijkstra::dist[v])
{
if (!p)
{
G[].add(u, v, w, id);
++in[v];
}
else
{
G[].add(v, u, w, id);
++in[u];
}
}
} queue <int> q;
for (int u = ; u <= n; ++u) if (Dijkstra::dist[u] != INF && !in[u])
{
x[u] = ;
q.push(u);
} while (!q.empty())
{
int u = q.front(); q.pop();
erp(G[], u)
{
x[v] += x[u];
--in[v];
if (!in[v]) q.push(v);
}
}
} void Run()
{
while (scanf("%d%d", &n, &m) != EOF)
{
G[].init();
memset(ans, , sizeof ans);
for (int i = , u, v, w; i <= m; ++i)
{
scanf("%d%d%d", &u, &v, &w);
G[].add(u, v, w, i);
}
for (int i = ; i <= n; ++i)
{
Dijkstra::work(i);
Topo(, g);
Topo(, f);
for (int u = ; u <= n; ++u) erp(G[], u)
ans[id] = (ans[id] + 1ll * f[u] * g[v]) % MOD;
}
for (int i = ; i <= m; ++i) printf("%lld\n", ans[i]);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

2752:线段树维护,注意区间的合并

 #include <bits/stdc++.h>
using namespace std; #define N 100010
#define ll long long
int n, q; ll calc(ll x) { return x * (x + ) / ; }
ll base[N];
struct SEG
{
struct node
{
ll sum, res, lsum, rsum, lazy, cnt, sze;
node() {}
node(ll sum, ll res, ll lsum, ll rsum, ll lazy, ll cnt, ll sze) : sum(sum), res(res), lsum(lsum), rsum(rsum), lazy(lazy), cnt(cnt), sze(sze) {}
node operator + (const node &r) const
{
node ans = node(, , , , , , );
ans.sum = sum + r.sum;
ans.res = res + r.res + rsum * r.cnt + r.lsum * cnt;
ans.lsum = lsum + r.lsum + sum * r.cnt;
ans.rsum = rsum + r.rsum + r.sum * cnt;
ans.cnt = cnt + r.cnt;
ans.sze = sze + r.sze + cnt * r.cnt;
return ans;
}
}a[N << ], res;
void change(int id, ll val)
{
a[id].sum += a[id].cnt * val;
a[id].res += base[a[id].cnt] * val;
a[id].lsum += calc(a[id].cnt) * val;
a[id].rsum += calc(a[id].cnt) * val;
a[id].lazy += val;
}
void pushdown(int id)
{
if (!a[id].lazy) return;
change(id << , a[id].lazy);
change(id << | , a[id].lazy);
a[id].lazy = ;
}
void build(int id, int l, int r)
{
if (l == r)
{
a[id] = node(, , , , , , );
return;
}
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
a[id] = a[id << ] + a[id << | ];
}
void update(int id, int l, int r, int ql, int qr, ll val)
{
if (l >= ql && r <= qr)
{
change(id, val);
return;
}
pushdown(id);
int mid = (l + r) >> ;
if (ql <= mid) update(id << , l, mid, ql, qr, val);
if (qr > mid) update(id << | , mid + , r, ql, qr, val);
a[id] = a[id << ] + a[id << | ];
return;
}
node query(int id, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr) return a[id];
pushdown(id);
int mid = (l + r) >> ;
node res = node(, , , , , , );
if (ql <= mid) res = query(id << , l, mid, ql, qr);
if (qr > mid) res = res.cnt ? res + query(id << | , mid + , r, ql, qr) : query(id << | , mid + , r, ql, qr);
a[id] = a[id << ] + a[id << | ];
return res;
}
}seg; ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; } void Run()
{
for (int i = ; i <= ; ++i) base[i] = base[i - ] + calc(i);
while (scanf("%d%d", &n, &q) != EOF)
{
seg.build(, , n);
char op; int l, r, v;
for (int i = ; i <= q; ++i)
{
scanf(" %c%d%d", &op, &l, &r); ++l;
if (op == 'C')
{
scanf("%d", &v);
seg.update(, , n, l, r, v);
}
else
{
seg.res = seg.query(, , n, l, r);
ll a = seg.res.res, b = seg.res.sze;
ll t = gcd(a, b);
a /= t, b /= t;
printf("%lld/%lld\n", a, b);
}
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

3100:单调队列维护左端点,枚举右端点

 #include <bits/stdc++.h>
using namespace std; #define N 1000001
int n, res;
int arr[N], pre[N], q[N]; void check(int l, int r, int pos)
{
if (pos > r) return;
if (r - l + == arr[pos]) res = max(res, r - l + );
} void Run()
{
while (scanf("%d", &n) != EOF)
{
res = ;
int l = , r = , L = ;
for (int i = ; i <= n; ++i)
{
scanf("%d", arr + i);
L = max(L, pre[arr[i]] + );
while (l <= r && q[l] <= pre[arr[i]])
{
check(q[l] + , i - , q[l + ]);
++l;
}
pre[arr[i]] = i;
while (l <= r && arr[i] >= arr[q[r]])
{
check(max(L, q[r - ] + ), i - , q[r]);
--r;
}
q[++r] = i;
check(L, i, q[l]);
}
printf("%d\n", res);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ; }

3110:整体二分+线段树

 #include <bits/stdc++.h>
using namespace std; #define N 50010
#define ll long long int n, q, m;
ll ans[N]; struct SEG
{
struct node
{
ll cnt, lazy, sum;
node() {}
node(int l, int r)
{
cnt = r - l + ;
lazy = sum = ;
}
}a[N << ]; void pushup(int id)
{
a[id].sum = a[id << ].sum + a[id << | ].sum;
} void pushdown(int id)
{
if (a[id].lazy)
{
int lazy = a[id].lazy; a[id].lazy = ;
a[id << ].lazy += lazy;
a[id << | ].lazy += lazy;
a[id << ].sum += lazy * a[id << ].cnt;
a[id << | ].sum += lazy * a[id << | ].cnt;
}
} void build(int id, int l, int r)
{
a[id] = node(l, r);
if (l == r) return;
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
} void update(int id, int l, int r, int ql, int qr, ll val)
{
if (l >= ql && r <= qr)
{
a[id].lazy += val;
a[id].sum += val * a[id].cnt;
return;
}
pushdown(id);
int mid = (l + r) >> ;
if (ql <= mid) update(id << , l, mid, ql, qr, val);
if (qr > mid) update(id << | , mid + , r, ql, qr, val);
pushup(id);
} ll query(int id, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr) return a[id].sum;
pushdown(id);
int mid = (l + r) >> ;
ll res = ;
if (ql <= mid) res += query(id << , l, mid, ql, qr);
if (qr > mid) res += query(id << | , mid + , r, ql, qr);
pushup(id);
return res;
}
}segtree; struct QUE
{
int op, x, y, id; ll c;
void scan()
{
scanf("%d%d%d%lld", &op, &x, &y, &c);
if (op == ) id = ++m;
}
}que[N], quel[N], quer[N]; void solve(int ql, int qr, int l, int r)
{
if (ql > qr) return;
if (l == r)
{
for (int i = ql; i <= qr; ++i) if (que[i].op == )
ans[que[i].id] = l;
return;
}
int mid = (l + r) >> , cnt_ql = , cnt_qr = ;
for (int i = ql; i <= qr; ++i)
{
if (que[i].op == )
{
if (que[i].c > mid) segtree.update(, , n, que[i].x, que[i].y, ), quer[++cnt_qr] = que[i];
else quel[++cnt_ql] = que[i];
}
else
{
ll tmp = segtree.query(, , n, que[i].x, que[i].y);
if (tmp < que[i].c) que[i].c -= tmp, quel[++cnt_ql] = que[i];
else quer[++cnt_qr] = que[i];
}
}
for (int i = ; i <= cnt_qr; ++i) if (quer[i].op == ) segtree.update(, , n, quer[i].x, quer[i].y, -);
for (int i = ; i <= cnt_ql; ++i) que[ql + i - ] = quel[i];
for (int i = ; i <= cnt_qr; ++i) que[ql + cnt_ql + i - ] = quer[i];
solve(ql, ql + cnt_ql - , l, mid);
solve(ql + cnt_ql, qr, mid + , r);
} void Run()
{
while (scanf("%d%d", &n, &q) != EOF)
{
for (int i = ; i <= q; ++i) que[i].scan();
segtree.build(, , n);
solve(, q, -N, N);
for (int i = ; i <= m; ++i) printf("%lld\n", ans[i]);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

3155:硬核线段树

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 100010
int n, m;
ll arr[N]; struct SEG
{
ll sum[N << ][];
int cnt[N << ];
void pushup(int id)
{
sum[id][] = sum[id << ][] + sum[id << | ][];
sum[id][] = sum[id << ][] + sum[id << | ][] + cnt[id << | ] * sum[id << ][];
}
void build(int id, int l, int r)
{
cnt[id] = r - l + ;
if (l == r)
{
sum[id][] = sum[id][] = arr[l];
return;
}
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
pushup(id);
}
void update(int id, int l, int r, int pos, ll val)
{
if (l == r)
{
sum[id][] = sum[id][] = val;
return;
}
int mid = (l + r) >> ;
if (pos <= mid) update(id << , l, mid, pos, val);
else update(id << | , mid + , r, pos, val);
pushup(id);
}
ll query(int id, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr) return sum[id][] * (qr - r) + sum[id][];
int mid = (l + r) >> ;
ll res = ;
if (ql <= mid) res += query(id << , l, mid, ql, qr);
if (qr > mid) res += query(id << | , mid + , r, ql, qr);
return res;
}
}seg; void Run()
{
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%lld", arr + i);
seg.build(, , n);
char op[]; int x, y;
for (int i = ; i <= m; ++i)
{
scanf("%s%d", op, &x);
if (op[] == 'Q') printf("%lld\n", seg.query(, , n, , x));
else
{
scanf("%d", &y);
seg.update(, , n, x, y);
}
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ; }

3173:离线+BIT+二分

 #include <bits/stdc++.h>
using namespace std; #define N 100010
int n;
int a[N], b[N], ans[N]; struct BIT_Max
{
int a[N];
void init() { memset(a, , sizeof a); }
void update(int x, int val) { for (; x <= n; x += x & -x) a[x] = max(a[x], val); }
int query(int x) { int res = ; for (; x; x -= x & -x) res = max(res, a[x]); return res; }
}bit_max; struct BIT_sum
{
int a[N];
void init() { memset(a, , sizeof a); }
void update(int x, int val) { for (; x <= n; x += x & -x) a[x] += val; }
int query(int x) { int res = ; for (; x; x -= x & -x) res += a[x]; return res; }
}bit_sum; void Run()
{
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%d", a + i), ++a[i];
bit_sum.init();
for (int i = ; i <= n; ++i) bit_sum.update(i, );
for (int i = n; i >= ; --i)
{
int l = , r = n, pos;
while (r - l >= )
{
int mid = (l + r) >> ;
int num = bit_sum.query(mid);
if (num == a[i])
pos = mid;
if (num >= a[i]) r = mid - ;
else l = mid + ;
}
b[i] = pos;
bit_sum.update(pos, -);
}
bit_max.init();
for (int i = ; i <= n; ++i)
{
int res = bit_max.query(b[i]) + ;
bit_max.update(b[i], res);
ans[i] = bit_max.query(n);
}
for (int i = ; i <= n; ++i) printf("%d\n", ans[i]);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ; }

3262:CDQ分治解决一维,考虑有重复的,将id加入形成四关键字排序使得排序顺序固定,然后前后各扫一遍更新最大答案

 #include <bits/stdc++.h>
using namespace std; #define N 200010 int n, k;
int ans[N], cnt[N]; struct node
{
int x, y, z, id;
bool isleft;
void scan(int id)
{
this->id = id;
scanf("%d%d%d", &x, &y, &z);
}
bool operator < (const node &r) const
{
return x == r.x ? (y == r.y ? (z == r.z ? id < r.id : z < r.z) : y < r.y) : x < r.x;
}
bool operator == (const node &r) const { return x == r.x && y == r.y && z == r.z; }
}arr[N], tarr[N]; struct BIT
{
int a[N]; void update(int x, int val)
{
while (x <= k)
{
a[x] += val;
x += x & -x;
}
} int query(int x)
{
int res = ;
while (x)
{
res += a[x];
x -= x & -x;
}
return res;
}
}bit; bool cmp(node a, node b)
{
return a.y == b.y ? (a.z == b.z ? (a.x == b.x ? a.id < b.id : a.x < b.x) : a.z < b.z) : a.y < b.y;
} void CDQ(int l, int r)
{
if (l == r) return;
int mid = (l + r) >> ;
CDQ(l, mid); CDQ(mid + , r);
for (int i = l; i <= r; ++i)
{
tarr[i] = arr[i];
if (i <= mid) tarr[i].isleft = true;
else tarr[i].isleft = false;
}
sort(tarr + l, tarr + r + , cmp);
for (int i = l; i <= r; ++i)
{
if (tarr[i].isleft) bit.update(tarr[i].z, );
else ans[tarr[i].id] += bit.query(tarr[i].z);
}
for (int i = l; i <= r; ++i) if (tarr[i].isleft) bit.update(tarr[i].z, -);
} void Run()
{
while (scanf("%d%d", &n, &k) != EOF)
{
for (int i = ; i <= n; ++i) arr[i].scan(i), ans[i] = ;
sort(arr + , arr + + n);
CDQ(, n);
for (int i = n - ; i >= ; --i) if (arr[i] == arr[i + ])
ans[arr[i].id] = max(ans[arr[i].id], ans[arr[i + ].id]);
for (int i = ; i <= n; ++i) if (arr[i] == arr[i - ])
ans[arr[i].id] = max(ans[arr[i].id], ans[arr[i - ].id]);
for (int i = ; i <= n; ++i) ++cnt[ans[i]];
for (int i = ; i < n; ++i) printf("%d\n", cnt[i]);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

3295:考虑(t, p, x) 三维偏序问题,分别表示删除的时间,删除的位置,删除的值  用CDQ分治干掉t, 排序干掉p,树状数组干掉x

 #include <bits/stdc++.h>
using namespace std; #define N 100010
#define ll long long int n, m, ttm;
int arr[N], pos[N];
ll ans[N];
bool flag[N]; struct QUE
{
int t, p, x;
QUE() {}
QUE(int t, int p, int x) : t(t), p(p), x(x) {}
bool operator < (const QUE &r) const
{
return p < r.p;
}
}q[N], tq[N]; struct BIT
{
int a[N]; void Init()
{
memset(a, , sizeof a);
} void update(int x, int val)
{
while (x <= n)
{
a[x] += val;
x += x & -x;
}
} int query(int x)
{
int res = ;
while (x)
{
res += a[x];
x -= x & -x;
}
return res;
}
}bit; void CDQ(int l, int r)
{
if (l == r) return;
int mid = (l + r) >> ;
CDQ(l, mid); CDQ(mid + , r);
for (int i = l; i <= r; ++i)
{
tq[i] = q[i];
if (i > mid) tq[i].t = ;
}
sort(tq + l, tq + r + );
for (int i = l; i <= r; ++i)
{
if (!tq[i].t) bit.update(tq[i].x, );
else ans[tq[i].t] += bit.query(n) - bit.query(tq[i].x);
}
for (int i = l; i <= r; ++i) if (!tq[i].t) bit.update(tq[i].x, -);
for (int i = r; i >= l; --i)
{
if (!tq[i].t) bit.update(tq[i].x, );
else ans[tq[i].t] += bit.query(tq[i].x);
}
for (int i = l; i <= r; ++i) if (!tq[i].t) bit.update(tq[i].x, -);
} void Run()
{
while (scanf("%d%d", &n, &m) != EOF)
{
ttm = m; bit.Init();
memset(ans, , sizeof ans);
memset(flag, , sizeof flag);
for (int i = ; i <= n; ++i)
{
scanf("%d", arr + i);
pos[arr[i]] = i;
}
for (int i = , x; i <= m; ++i)
{
scanf("%d", &x);
flag[x] = ;
q[i] = QUE(i, pos[x], x);
}
for (int i = ; i <= n; ++i) if (!flag[i])
q[++ttm] = QUE(ttm, pos[i], i);
CDQ(, n);
for (int i = n - ; i >= ; --i) ans[i] += ans[i + ];
for (int i = ; i <= m; ++i) printf("%lld\n", ans[i]);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

3319:考虑一个黑点产生的影响,即只对它的子树产生影响,再用并查集缩点,这样一个点只会处理一次,加了IO优化才过的,应该不是正解。

 #include <bits/stdc++.h>
using namespace std; #define N 1000010
int n, q;
int lp[N], rp[N], pos[N], deep[N], fa[N], cnt;
struct Edge { int to, nx; }edge[N << ];
int head[N], cntedge;
void add(int u, int v) { edge[++cntedge] = Edge{ v, head[u] }; head[u] = cntedge; } void DFS(int u)
{
lp[u] = ++cnt;
for (int it = head[u]; it; it = edge[it].nx)
{
int v = edge[it].to;
if (v == fa[u]) continue;
pos[v] = it >> ;
deep[v] = deep[u] + ;
fa[v] = u;
DFS(v);
}
rp[u] = cnt;
} struct SEG
{
int Max[N << ];
int max(int x, int y)
{
if (deep[x] < deep[y]) return y;
return x;
}
void update(int id, int l, int r, int ql, int qr, int val)
{
if (l >= ql && r <= qr)
{
Max[id] = max(Max[id], val);
return;
}
int mid = (l + r) >> ;
if (ql <= mid) update(id << , l, mid, ql, qr, val);
if (qr > mid) update(id << | , mid + , r, ql, qr, val);
}
int query(int id, int l, int r, int pos)
{
if (l == r) return Max[id];
int mid = (l + r) >> ;
if (pos <= mid) return max(Max[id], query(id << , l, mid, pos));
else return max(Max[id], query(id << | , mid + , r, pos));
}
}seg; int pre[N];
int find(int x) { return pre[x] == ? x : pre[x] = find(pre[x]); } void modify(int u, int v)
{
u = find(u), v = find(v);
while (u != v)
{
if (deep[find(fa[u])] < deep[find(fa[v])])
swap(u, v);
seg.update(, , n, lp[u], rp[u], u);
pre[u] = fa[u]; u = find(u);
}
} namespace FastIO
{
#define BUF_SIZE 10000005
bool IOerror = false;
inline char NC()
{
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if (p1 == pend)
{
p1 = buf;
pend = buf + fread(buf, , BUF_SIZE, stdin);
if (pend == p1)
{
IOerror = true;
return -;
}
}
return *p1++;
}
inline bool blank(char ch)
{
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
template <typename T>
inline void read(T &x)
{
char ch;
while (blank(ch = NC()));
if (IOerror)
{
x = -;
return;
}
bool flag = false;
if (ch == '-')
{
flag = true;
ch = NC();
}
if (!isdigit(ch)) while (!isdigit(ch = NC()));
for (x = ch - ''; isdigit(ch = NC()); x = x * + ch - '');
if (flag) x *= -;
}
inline void out(int x)
{
if (x / ) out(x / );
putchar(x % + '');
}
inline void output(int x) { out(x), putchar('\n'); }
#undef BUF_SIZE
}using namespace FastIO; void Run()
{
while (read(n), n != EOF)
{
read(q);
deep[] = ; cntedge = ;
for (int i = , u, v; i < n; ++i)
{
read(u), read(v);
add(u, v); add(v, u);
}
DFS();
for (int i = , op, u, v; i <= q; ++i)
{
read(op), read(v);
if (op == ) output(pos[seg.query(, , n, lp[v])]);
else
{
read(u);
modify(u, v);
}
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

3524:主席树

 #include <bits/stdc++.h>
using namespace std; #define N 500010
int n, q, m;
int arr[N], brr[N]; void Hash()
{
for (int i = ; i <= n; ++i) brr[i] = arr[i];
sort(brr + , brr + + n);
m = unique(brr + , brr + + n) - brr - ;
for (int i = ; i <= n; ++i) arr[i] = lower_bound(brr + , brr + + m, arr[i]) - brr;
} int T[N];
struct CHAIR
{
#define M N * 40
int a[M], ls[M], rs[M], cnt;
void build(int &id, int l, int r)
{
id = ++cnt;
a[id] = ;
if (l == r) return;
int mid = (l + r) >> ;
build(ls[id], l, mid);
build(rs[id], mid + , r);
}
int update(int pre, int pos)
{
int now = ++cnt, tmp = now;
a[now] = a[pre] + ;
int l = , r = m;
while (l < r)
{
int mid = (l + r) >> ;
if (pos <= mid)
{
ls[now] = ++cnt; rs[now] = rs[pre];
now = ls[now], pre = ls[pre];
r = mid;
}
else
{
ls[now] = ls[pre], rs[now] = ++cnt;
now = rs[now], pre = rs[pre];
l = mid + ;
}
a[now] = a[pre] + ;
}
return tmp;
}
int query(int lt, int rt, int cnt)
{
lt = T[lt], rt = T[rt];
int l = , r = m;
while (l < r)
{
int mid = (l + r) >> ;
int szel = a[ls[rt]] - a[ls[lt]];
int szer = a[rs[rt]] - a[rs[lt]];
if (szel > cnt)
{
lt = ls[lt];
rt = ls[rt];
r = mid;
}
else if (szer > cnt)
{
lt = rs[lt];
rt = rs[rt];
l = mid + ;
}
else
return ;
}
return l;
}
}chair; void Run()
{
while (scanf("%d%d", &n, &q) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%d", arr + i); Hash();
chair.build(T[], , m);
for (int i = ; i <= n; ++i) T[i] = chair.update(T[i - ], arr[i]);
for (int i = , l, r; i <= q; ++i)
{
scanf("%d%d", &l, &r);
printf("%d\n", brr[chair.query(l - , r, (r - l + ) >> )]);
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

3578:集合Hash : 给每个点随机Hash权值,所有点权异或起来便是集合Hash值, 插入删除均是异或,然后线段树维护有效人数

 #include <bits/stdc++.h>
using namespace std; #define N 100010
int n, m, q, ran;
int Hash[N], loc[N];
map <int, bool> mp; struct SEG
{
int Set[N << ], sum[N << ], peo[N << ], lazy[N << ];
void init()
{
memset(Set, , sizeof Set);
memset(sum, , sizeof sum);
memset(peo, , sizeof peo);
memset(lazy, , sizeof lazy);
}
void pushup(int id) { sum[id] = sum[id << ] + sum[id << | ]; }
void clear(int id, int l, int r)
{
lazy[id] = ; sum[id] = ;
if (l == r)
mp[Set[id]] = ;
}
void pushdown(int id, int l, int r, int mid)
{
if (lazy[id])
{
if (l == r)
{
lazy[id] = ;
return;
}
clear(id << , l, mid);
clear(id << | , mid + , r);
lazy[id] = ;
}
}
void update(int id, int l, int r, int pos, int p, int val)
{
if (l == r)
{
Set[id] ^= p;
peo[id] += val;
sum[id] = (mp.find(Set[id]) == mp.end() ? peo[id] : );
return;
}
int mid = (l + r) >> ;
pushdown(id, l, r, mid);
if (pos <= mid) update(id << , l, mid, pos, p, val);
else update(id << | , mid + , r, pos, p, val);
pushup(id);
} int query(int id, int l, int r, int ql, int qr)
{
int res = ;
if (l >= ql && r <= qr)
{
res = sum[id];
clear(id, l, r);
return res;
}
int mid = (l + r) >> ;
pushdown(id, l, r, mid);
if (ql <= mid) res += query(id << , l, mid, ql, qr);
if (qr > mid) res += query(id << | , mid + , r, ql, qr);
pushup(id);
return res;
}
}seg; void Run()
{
while (scanf("%d%d%d", &n, &m, &q) != EOF)
{
seg.init(); mp.clear();
for (int i = ; i <= n; ++i)
{
ran *= ;
ran += ;
seg.update(, , m, loc[i] = , Hash[i] = ran, );
}
char op; int x, y;
for (int i = ; i <= q; ++i)
{
scanf(" %c%d%d", &op, &x, &y);
if (op == 'C')
{
seg.update(, , m, loc[x], Hash[x], -);
seg.update(, , m, loc[x] = y, Hash[x], );
}
else
printf("%d\n", seg.query(, , m, x, y));
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

3589:可持久化线段树+树剖

 #include <bits/stdc++.h>
using namespace std; #define N 200010
#define ll long long
ll const MOD = (ll)1ll << ;
int n, q;
struct Edge { int to, nx; }edge[N << ];
int head[N], cntedge;
void addedge(int u, int v) { edge[++cntedge] = Edge{ v, head[u] }; head[u] = cntedge; }
int p[N], lp[N], rp[N], sze[N], son[N], fa[N], deep[N], top[N], cntdfs; void DFS(int u)
{
sze[u] = ;
for (int it = head[u]; ~it; it = edge[it].nx)
{
int v = edge[it].to;
if (v == fa[u]) continue;
deep[v] = deep[u] + ;
fa[v] = u;
DFS(v); sze[u] += sze[v];
if (son[u] == - || sze[v] > sze[son[u]]) son[u] = v;
}
} void getpos(int u, int sp)
{
top[u] = sp;
p[u] = ++cntdfs;
lp[u] = cntdfs;
if (son[u] == -)
{
rp[u] = cntdfs;
return;
}
getpos(son[u], sp);
for (int it = head[u]; ~it; it = edge[it].nx)
{
int v = edge[it].to;
if (v == fa[u] || v == son[u]) continue;
getpos(v, v);
}
rp[u] = cntdfs;
} int T[];
struct SEG
{
#define M N * 60
int cnt;
struct node
{
int ls, rs, pre;
ll sum, lazy;
node() {}
node(int ls, int rs, int pre, ll sum, ll lazy) : ls(ls), rs(rs), pre(pre), sum(sum), lazy(lazy) {}
}a[M];
void pushup(int id)
{
int ls = a[id].ls, rs = a[id].rs;
a[id].sum = (a[ls].sum + a[rs].sum) % MOD;
}
void createson(int &now, int pre)
{
now = ++cnt;
a[now] = node(-, -, pre, , -);
return;
}
void pushdown(int id, int l, int r)
{
if (a[id].lazy == ) return;
int mid = (l + r) >> ;
if (a[id].ls == - || a[id].rs == -)
{
int pre = a[id].pre;
createson(a[id].ls, a[pre].ls);
createson(a[id].rs, a[pre].rs);
}
int ls = a[id].ls, rs = a[id].rs;
if (a[id].lazy == -)
{
a[id].lazy = ;
a[ls].lazy = a[rs].lazy = -;
a[ls].sum = a[rs].sum = ;
return;
}
ll lazy = a[id].lazy; a[id].lazy = ;
a[ls].lazy = (a[ls].lazy + lazy) % MOD; a[ls].sum = (a[ls].sum + lazy * (mid - l + ) % MOD) % MOD;
a[rs].lazy = (a[rs].lazy + lazy) % MOD; a[rs].sum = (a[rs].sum + lazy * (r - mid) % MOD) % MOD;
}
void build(int &id, int l, int r)
{
id = ++cnt;
a[id] = node(-, -, -, , );
if (l == r) return;
int mid = (l + r) >> ;
build(a[id].ls, l, mid);
build(a[id].rs, mid + , r);
}
void update(int id, int l, int r, int ql, int qr, ll val)
{
if (l >= ql && r <= qr)
{
a[id].lazy = (a[id].lazy + val) % MOD;
a[id].sum = (a[id].sum + val * (r - l + ) % MOD) % MOD;
return;
}
pushdown(id, l, r);
int mid = (l + r) >> ;
if (ql <= mid) update(a[id].ls, l, mid, ql, qr, val);
if (qr > mid) update(a[id].rs, mid + , r, ql, qr, val);
pushup(id);
}
void update(int &now, int pre, int l, int r, int ql, int qr, ll val)
{
now = ++cnt;
a[now] = node(-, -, pre, a[pre].sum, a[pre].lazy);
if (l >= ql && r <= qr)
{
a[now].lazy = -;
a[now].sum = ;
return;
}
pushdown(pre, l, r);
int mid = (l + r) >> ;
if (ql <= mid) update(a[now].ls, a[pre].ls, l, mid, ql, qr, val);
else a[now].ls = a[pre].ls;
if (qr > mid) update(a[now].rs, a[pre].rs, mid + , r, ql, qr, val);
else a[now].rs = a[pre].rs;
pushup(now);
}
ll query(int id, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr) return a[id].sum;
pushdown(id, l, r);
int mid = (l + r) >> ;
ll res = ;
if (ql <= mid) res = (res + query(a[id].ls, l, mid, ql, qr)) % MOD;
if (qr > mid) res = (res + query(a[id].rs, mid + , r, ql, qr)) % MOD;
pushup(id);
return res;
}
}seg; ll query(int u, int v, int now)
{
ll res = ;
while (top[u] != top[v])
{
if (deep[top[u]] < deep[top[v]]) swap(u, v);
res = (res + seg.query(now, , n, p[top[u]], p[u])) % MOD;
u = fa[top[u]];
}
if (deep[u] > deep[v]) swap(u, v);
res = (res + seg.query(now, , n, p[u], p[v])) % MOD;
return res;
} void update(int u, int v, int &now, int pre)
{
while (top[u] != top[v])
{
if (deep[top[u]] < deep[top[v]]) swap(u, v);
seg.update(now, pre, , n, p[top[u]], p[u], );
pre = now;
u = fa[top[u]];
}
if (deep[u] > deep[v]) swap(u, v);
seg.update(now, pre, , n, p[u], p[v], );
} void init()
{
memset(head, -, sizeof head);
memset(son, -, sizeof son);
cntedge = ;
cntdfs = ;
seg.cnt = ;
seg.build(T[], , n);
} void Run()
{
while (scanf("%d", &n) != EOF)
{
init();
for (int i = , u, v; i < n; ++i)
{
scanf("%d%d", &u, &v);
addedge(u, v);
addedge(v, u);
}
DFS(); getpos(, );
scanf("%d", &q);
for (int i = , op; i <= q; ++i)
{
scanf("%d", &op);
if (op == )
{
int u; ll x;
scanf("%d%lld", &u, &x);
if (x == ) continue;
seg.update(T[], , n, lp[u], rp[u], x);
}
else
{
int k, u, v;
scanf("%d", &k);
ll res = ;
int tmp = seg.cnt;
for (int j = ; j < k; ++j)
{
scanf("%d%d", &u, &v);
res = (res + query(u, v, T[j])) % MOD;
T[j + ] = ;
if (j != k - ) update(u, v, T[j + ], T[j]);
}
printf("%lld\n", res);
seg.cnt = tmp;
}
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

3626:差分+离线+树剖

 #include <bits/stdc++.h>
using namespace std; #define N 50010
int n, q;
vector <int> G[N];
struct qnode { int root, id, vis; };
vector <qnode> que[N];
int ans[N];
int p[N], sze[N], son[N], top[N], deep[N], fa[N], cnt; void DFS(int u)
{
sze[u] = ;
for (int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i];
deep[v] = deep[u] + ;
fa[v] = u;
DFS(v); sze[u] += sze[v];
if (son[u] == - || sze[v] > sze[son[u]]) son[u] = v;
}
} void getpos(int u, int sp)
{
top[u] = sp;
p[u] = ++cnt;
if (son[u] == -) return;
getpos(son[u], sp);
for (int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i];
if (v == son[u]) continue;
getpos(v, v);
}
} struct SEG
{
int sum[N << ], lazy[N << ];
void pushup(int id) { sum[id] = sum[id << ] + sum[id << | ]; }
void init()
{
memset(sum, , sizeof sum);
memset(lazy, , sizeof lazy);
}
void pushdown(int id, int l, int r)
{
if (!lazy[id]) return;
lazy[id << ] += lazy[id];
lazy[id << | ] += lazy[id];
int mid = (l + r) >> ;
sum[id << ] += lazy[id] * (mid - l + );
sum[id << | ] += lazy[id] * (r - mid);
lazy[id] = ;
}
void update(int id, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr)
{
sum[id] += (r - l + );
++lazy[id];
return;
}
pushdown(id, l, r);
int mid = (l + r) >> ;
if (ql <= mid) update(id << , l, mid, ql, qr);
if (qr > mid) update(id << | , mid + , r, ql, qr);
pushup(id);
}
int query(int id, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr) return sum[id];
pushdown(id, l, r);
int mid = (l + r) >> ;
int res = ;
if (ql <= mid) res += query(id << , l, mid, ql, qr);
if (qr > mid) res += query(id << | , mid + , r, ql, qr);
pushup(id);
return res;
}
}seg; void update(int u)
{
while (top[u] != )
{
seg.update(, , n, p[top[u]], p[u]);
u = fa[top[u]];
}
seg.update(, , n, p[], p[u]);
} int query(int u)
{
int res = ;
while (top[u] != )
{
res += seg.query(, , n, p[top[u]], p[u]);
u = fa[top[u]];
}
res += seg.query(, , n, p[], p[u]);
return res;
} void init()
{
for (int i = ; i <= n; ++i) G[i].clear(), que[i].clear();
memset(ans, , sizeof ans);
memset(son, -, sizeof son);
seg.init();
cnt = ;
} void Run()
{
while (scanf("%d%d", &n, &q) != EOF)
{
init();
for (int i = , u; i <= n; ++i)
{
scanf("%d", &u); ++u;
G[u].push_back(i);
}
for (int i = , l, r, z; i <= q; ++i)
{
scanf("%d%d%d", &l, &r, &z); ++r; ++z;
que[l].push_back(qnode{ z, i, - });
que[r].push_back(qnode{ z, i, });
}
DFS(); getpos(, );
for (int i = ; i <= n; ++i)
{
update(i);
for (int j = , len = que[i].size(); j < len; ++j)
{
int z = que[i][j].root, vis = que[i][j].vis, id = que[i][j].id;
ans[id] += vis * query(z);
}
}
for (int i = ; i <= q; ++i) printf("%d\n", ans[i] % );
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ; }

3694:最短路树上枚举非树边+树剖

 #include <bits/stdc++.h>
using namespace std; #define N 4010
#define M 100010
#define INF 0x3f3f3f3f
int n, m; struct Graph
{
struct node
{
int to, nx, w, vis;
node () {}
node(int to, int nx, int w, int vis) : to(to), nx(nx), w(w), vis(vis) {}
}a[M << ]; int head[N], pos;
void init()
{
memset(head, -, sizeof head);
pos = ;
}
void add(int u, int v, int w, int vis)
{
a[++pos] = node(v, head[u], w, vis); head[u] = pos;
a[++pos] = node(u, head[v], w, vis); head[v] = pos;
}
}G[];
#define erp(G, u) for (int it = G.head[u], v = G.a[it].to, w = G.a[it].w, vis = G.a[it].vis; ~it; it = G.a[it].nx, v = G.a[it].to, w = G.a[it].w, vis = G.a[it].vis) int fa[N], dis[N], deep[N], sze[N], son[N], top[N], p[N], fp[N], cnt;
void DFS(int u)
{
sze[u] = ;
erp(G[], u) if (v != fa[u])
{
fa[v] = u;
dis[v] = dis[u] + w;
deep[v] = deep[u] + ;
DFS(v); sze[u] += sze[v];
if (!son[u] || sze[v] > sze[son[u]]) son[u] = v;
}
} void getpos(int u, int sp)
{
top[u] = sp;
p[u] = ++cnt;
fp[cnt] = u;
if (!son[u]) return;
getpos(son[u], sp);
erp(G[], u) if (v != fa[u] && v != son[u])
getpos(v, v);
} struct SEG
{
int Min[N << ];
void build(int id, int l, int r)
{
Min[id] = INF;
if (l == r) return;
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
}
void update(int id, int l, int r, int ql, int qr, int val)
{
if (l >= ql && r <= qr)
{
Min[id] = min(Min[id], val);
return;
}
int mid = (l + r) >> ;
if (ql <= mid) update(id << , l, mid, ql, qr, val);
if (qr > mid) update(id << | , mid + , r, ql, qr, val);
}
int query(int id, int l, int r, int pos)
{
if (l == r) return Min[id];
int mid = (l + r) >> ;
int res = Min[id];
if (pos <= mid) res = min(res, query(id << , l, mid, pos));
else res = min(res, query(id << | , mid + , r, pos));
return res;
}
}seg; int querylca(int u, int v)
{
while (top[u] != top[v])
{
if (deep[top[u]] < deep[top[v]]) swap(u, v);
u = fa[top[u]];
}
if (deep[u] > deep[v]) swap(u, v);
return u;
} void update(int u, int v, int val)
{
if (u == v) return;
while (top[u] != top[v])
{
if (deep[top[u]] < deep[top[v]]) swap(u, v);
seg.update(, , n, p[top[u]], p[u], val);
u = fa[top[u]];
}
if (u == v) return;
if (deep[u] > deep[v]) swap(u, v);
seg.update(, , n, p[son[u]], p[v], val);
} void init()
{
memset(son, , sizeof son);
cnt = ;
G[].init(); G[].init();
} void Run()
{
while (scanf("%d%d", &n, &m) != EOF)
{
init();
for (int i = , u, v, w, vis; i <= m; ++i)
{
scanf("%d%d%d%d", &u, &v, &w, &vis);
G[].add(u, v, w, vis);
if (vis) G[].add(u, v, w, vis);
} DFS(); getpos(, ); seg.build(, , n);
for (int i = ; i <= n; ++i)
{
erp(G[], i) if (!vis)
{
int lca = querylca(i, v);
update(i, lca, dis[i] + dis[v] + w);
}
}
for (int i = ; i <= n; ++i)
{
int res = seg.query(, , n, p[i]);
printf("%d%c", res == INF ? - : res - dis[i], " \n"[i == n]);
} }
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

3744:分块+树状数组+主席树

 #include <bits/stdc++.h>
using namespace std; #define N 50010
#define block 250 int n, m, q;
int arr[N], brr[N], f[block + ][N]; struct BIT
{
int a[N];
void init() { memset(a, , sizeof a); }
void update(int x, int val) { for (; x <= m; x += x & -x) a[x] += val; }
int query(int x) { int res = ; for (; x; x -= x & -x) res += a[x]; return res; }
}bit; void Hash()
{
for (int i = ; i <= n; ++i) brr[i] = arr[i];
sort(brr + , brr + + n);
m = unique(brr + , brr + + n) - brr - ;
for (int i = ; i <= n; ++i) arr[i] = lower_bound(brr + , brr + + m, arr[i]) - brr;
} struct CHAIR
{
#define M N * 50
int T[N], L[M], R[M], C[M], cnt;
void init(){ cnt = ; }
int build(int l, int r)
{
int root = cnt++;
C[root] = ;
if (l < r)
{
int mid = (l + r) >> ;
L[root] = build(l, mid);
R[root] = build(mid + , r);
}
return root;
}
int update(int root, int pos)
{
int newroot = cnt++, tmp = newroot;
C[newroot] = C[root] + ;
int l = , r = m;
while (l < r)
{
int mid = (l + r) >> ;
if (pos <= mid)
{
L[newroot] = cnt++; R[newroot] = R[root];
newroot = L[newroot], root = L[root];
r = mid;
}
else
{
L[newroot] = L[root], R[newroot] = cnt++;
newroot = R[newroot], root = R[root];
l = mid + ;
}
C[newroot] = C[root] + ;
}
return tmp;
}
int query(int left, int right, int pos)
{
int res = ;
int l = , r = m;
while (l < r)
{
int mid = (l + r) >> ;
if (pos <= mid)
{
left = L[left];
right = L[right];
r = mid;
}
else
{
res += C[L[right]] - C[L[left]];
left = R[left];
right = R[right];
l = mid + ;
}
}
return res;
}
}chair; void Run()
{
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%d", arr + i); Hash();
for (int i = ; (i - ) * block + <= n; ++i)
{
int st = (i - ) * block + ;
bit.init();
for (int j = st; j <= n; ++j)
{
bit.update(arr[j], );
f[i][j] = f[i][j - ] + (j - st + ) - bit.query(arr[j]);
}
}
chair.T[] = chair.build(, m);
for (int i = ; i <= n; ++i) chair.T[i] = chair.update(chair.T[i - ], arr[i]);
scanf("%d", &q); bit.init();
int res = ;
for (int i = , l, r; i <= q; ++i)
{
scanf("%d%d", &l, &r);
l ^= res, r ^= res;
res = ;
if ((l - ) / block == (r - ) / block)
{
for (int j = l; j <= r; ++j)
{
bit.update(arr[j], );
res += (j - l + ) - bit.query(arr[j]);
}
for (int j = l; j <= r; ++j) bit.update(arr[j], -);
}
else
{
int nx = (l - ) / block + ;
res += f[nx + ][r];
for (int j = l; j <= nx * block; ++j) res += chair.query(chair.T[j], chair.T[r], arr[j]);
}
printf("%d\n", res);
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

3809:莫队+分块

 #include <bits/stdc++.h>
using namespace std; #define N 100010
#define block 450 int n, q;
int arr[N];
struct qnode
{
int l, r, a, b, id;
void scan(int id) { this->id = id; scanf("%d%d%d%d", &l, &r, &a, &b); }
bool operator < (const qnode &r) const
{
int posl = l / block, posr = r.l / block;
return posl == posr ? this->r < r.r : posl < posr;
}
}que[N * ]; int ans[N * ]; int cnt[N], cntblock[block];
void update(int x, int val)
{
if (val == )
{
if (cnt[arr[x]] == ) ++cntblock[(arr[x] - ) / block];
++cnt[arr[x]];
}
else
{
if (cnt[arr[x]] == ) --cntblock[(arr[x] - ) / block];
--cnt[arr[x]];
}
} int query(int l, int r)
{
int posl = (l - ) / block, posr = (r - ) / block;
int res = ;
if (posl == posr)
{
for (int i = l; i <= r; ++i) if (cnt[i])
++res;
}
else
{
for (int i = l; i <= (posl + ) * block; ++i) if (cnt[i])
++res;
for (int i = posl + ; i < posr; ++i)
res += cntblock[i];
for (int i = posr * block + ; i <= r; ++i) if (cnt[i])
++res;
}
return res;
} void Run()
{
while (scanf("%d%d", &n, &q) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%d", arr + i);
for (int i = ; i <= q; ++i) que[i].scan(i);
sort(que + , que + + q);
memset(cnt, , sizeof cnt);
memset(cntblock, , sizeof cntblock);
for (int i = , l = , r = ; i <= q; ++i)
{
for (; r < que[i].r; ++r) update(r + , );
for (; r > que[i].r; --r) update(r, -);
for (; l < que[i].l; ++l) update(l, -);
for (; l > que[i].l; --l) update(l - , );
ans[que[i].id] = query(que[i].a, que[i].b);
}
for (int i = ; i <= q; ++i) printf("%d\n", ans[i]);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

3910:树剖

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 500010 int n, q, st;
vector <int> G[N];
int arr[N]; struct SEG
{
struct node
{
int l, r, vis, lazy;
node() {}
node(int l, int r)
{
this->l = l;
this->r = r;
vis = lazy = ;
}
}a[N << ];
void pushdown(int id)
{
if (a[id].lazy)
{
a[id].lazy = ;
a[id << ].vis = ;
a[id << ].lazy = ;
a[id << | ].vis = ;
a[id << | ].lazy = ;
}
}
void build(int id, int l, int r)
{
a[id] = node(l, r);
if (l == r) return;
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
}
void update(int id, int l, int r)
{
if (a[id].l >= l && a[id].r <= r)
{
a[id].vis = ;
a[id].lazy = ;
return;
}
pushdown(id);
int mid = (a[id].l + a[id].r) >> ;
if (l <= mid) update(id << , l, r);
if (r > mid) update(id << | , l, r);
}
int query(int id, int pos)
{
if (a[id].l == a[id].r) return a[id].vis;
pushdown(id);
int mid = (a[id].l + a[id].r) >> ;
return (pos <= mid ? query(id << , pos) : query(id << | , pos));
}
}seg; int p[N], fp[N], sze[N], son[N], top[N], fa[N], deep[N], cnt;
void DFS(int u)
{
sze[u] = ;
for (int i = , v, len = G[u].size(); i < len; ++i)
{
v = G[u][i];
if (v != fa[u])
{
fa[v] = u;
deep[v] = deep[u] + ;
DFS(v);
sze[u] += sze[v];
if (son[u] == - || sze[v] > sze[son[u]]) son[u] = v;
}
}
} void getpos(int u, int sp)
{
top[u] = sp;
p[u] = ++cnt;
fp[cnt] = u;
if (son[u] == -) return;
getpos(son[u], sp);
for (int i = , v, len = G[u].size(); i < len; ++i)
{
v = G[u][i];
if (v != fa[u] && v != son[u])
getpos(v, v);
}
} int modify(int u, int v)
{
int fu = top[u], fv = top[v];
while (fu != fv)
{
if (deep[fu] < deep[fv])
{
swap(fu, fv);
swap(u, v);
}
seg.update(, p[fu], p[u]);
u = fa[fu]; fu = top[u];
}
if (u == v) return u;
if (deep[u] > deep[v]) swap(u, v);
seg.update(, p[u], p[v]);
return u;
} void Run()
{
while (scanf("%d%d%d", &n, &q, &st) != EOF)
{
seg.build(, , n);
memset(son, -, sizeof son);
cnt = ;
for (int i = ; i <= n; ++i) G[i].clear();
for (int i = , u, v; i < n; ++i)
{
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
for (int i = ; i <= q; ++i) scanf("%d", arr + i);
DFS(); getpos(, );
ll res = ;
for (int i = ; i <= q; ++i)
{
if (seg.query(, p[arr[i]]) == )
{
int LCA = modify(st, arr[i]);
res += deep[st] + deep[arr[i]] - * deep[LCA];
st = arr[i];
}
}
printf("%lld\n", res);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ; }

4012:树剖+可持久化线段树(标记永久化)

 #include <bits/stdc++.h>
using namespace std; #define N 150010
#define ll long long
#define pii pair <int, int>
int n, q, a[N], age[N]; ll A;
ll sum[N]; struct Graph
{
struct node
{
int to, nx; int w;
node() {}
node(int to, int nx, int w) : to(to), nx(nx), w(w) {}
}a[N << ];
int head[N], pos;
void Init() { memset(head, , sizeof head); pos = ; }
void add(int u, int v, int w)
{
a[++pos] = node(v, head[u], w); head[u] = pos;
a[++pos] = node(u, head[v], w); head[v] = pos;
}
}G;
#define erp(u) for (int it = G.head[u], v = G.a[it].to, w = G.a[it].w; it; it = G.a[it].nx, v = G.a[it].to, w = G.a[it].w) ll dis[N], arr[N], prefix[N];
int p[N], fp[N], fa[N], deep[N], sze[N], son[N], top[N], cnt;
void DFS(int u)
{
sze[u] = ;
erp(u) if (v != fa[u])
{
fa[v] = u;
deep[v] = deep[u] + ;
dis[v] = dis[u] + w;
arr[v] = w;
DFS(v); sze[u] += sze[v];
if (!son[u] || sze[v] > sze[son[u]]) son[u] = v;
}
} void getpos(int u, int sp)
{
top[u] = sp;
p[u] = ++cnt;
fp[cnt] = u;
if (!son[u]) return;
getpos(son[u], sp);
erp(u) if (v != fa[u] && v != son[u])
getpos(v, v);
} int T[N];
struct SEG
{
#define M N * 75
struct node
{
int ls, rs; ll lazy, sum;
node() {}
node (int ls, int rs, ll lazy, ll sum) : ls(ls), rs(rs), lazy(lazy), sum(sum) {}
}a[M]; int cnt;
void build(int &now, int l, int r)
{
now = ++cnt;
a[now] = node(-, -, , );
if (l == r) return;
int mid = (l + r) >> ;
build(a[now].ls, l, mid);
build(a[now].rs, mid + , r);
}
void update(int &now, int pre, int l, int r, int ql, int qr)
{
now = ++cnt;
a[now] = a[pre];
a[now].sum += prefix[qr] - prefix[ql - ];
if (l >= ql && r <= qr)
{
++a[now].lazy;
return;
}
int mid = (l + r) >> ;
if (ql <= mid) update(a[now].ls, a[pre].ls, l, mid, ql, min(mid, qr));
if (qr > mid) update(a[now].rs, a[pre].rs, mid + , r, max(mid + , ql), qr);
}
ll query(int lt, int rt, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr) return a[rt].sum - a[lt].sum;
int mid = (l + r) >> ;
ll res = (a[rt].lazy - a[lt].lazy) * (prefix[qr] - prefix[ql - ]);
if (ql <= mid) res += query(a[lt].ls, a[rt].ls, l, mid, ql, min(mid, qr));
if (qr > mid) res += query(a[lt].rs, a[rt].rs, mid + , r, max(mid + , ql), qr);
return res;
}
}seg; void update(int u, int v, int &now, int pre)
{
now = pre;
while (top[u] != top[v])
{
if (deep[top[u]] < deep[top[v]]) swap(u, v);
seg.update(now, pre, , n, p[top[u]], p[u]);
pre = now;
u = fa[top[u]];
}
if (u == v) return;
if (deep[u] > deep[v]) swap(u, v);
seg.update(now, pre, , n, p[son[u]], p[v]);
} ll query(int u, int v, int lt, int rt)
{
ll res = ;
while (top[u] != top[v])
{
if (deep[top[u]] < deep[top[v]]) swap(u, v);
res += seg.query(lt, rt, , n, p[top[u]], p[u]);
u = fa[top[u]];
}
if (u == v) return res;
if (deep[u] > deep[v]) swap(u, v);
return res + seg.query(lt, rt, , n, p[son[u]], p[v]);
} bool cmp(int a, int b) { return age[a] < age[b]; } void init()
{
G.Init(); cnt = ; dis[] = ; deep[] = ;
seg.cnt = ; sum[] = ; arr[] = ;
memset(son, , sizeof son);
} void Run()
{
while (scanf("%d%d%lld", &n, &q, &A) != EOF)
{
init();
for (int i = ; i <= n; ++i) scanf("%d", age + i), a[i] = i;
sort(a + , a + + n, cmp);
sort(age + , age + + n);
for (int i = , u, v, w; i < n; ++i)
{
scanf("%d%d%d", &u, &v, &w);
G.add(u, v, w);
}
DFS(); getpos(, );
seg.build(T[], , n);
for (int i = ; i <= n; ++i) prefix[i] = prefix[i - ] + arr[fp[i]];
for (int i = ; i <= n; ++i)
{
update(, a[i], T[i], T[i - ]);
sum[i] = sum[i - ] + dis[a[i]];
}
ll res = ; int u; ll l, r;
for (int i = ; i <= q; ++i)
{
scanf("%d%lld%lld", &u, &l, &r);
l = (l + res) % A;
r = (r + res) % A;
if (l > r) swap(l, r);
int ql = lower_bound(age + , age + + n, l) - age;
int qr = upper_bound(age + , age + + n, r) - age - ;
if (ql > qr) res = ;
else
{
res = sum[qr] - sum[ql - ] + dis[u] * (qr - ql + );
res -= * query(, u, T[ql - ], T[qr]);
}
printf("%lld\n", res); res %= A;
}
}
} int main()
{
Run();
return ;
}

4236:考虑拆成两个等式判断L, R是否满足,再借助map快速找答案

 #include <bits/stdc++.h>
using namespace std; #define N 200010
int n, pos[N], J[N], O[N], I[N];
char s[N];
map <int, int> mp[N];
int Hasharr[N], m; void Hash()
{
for (int i = ; i <= n; ++i) Hasharr[i] = pos[i];
sort(Hasharr, Hasharr + + n);
m = unique(Hasharr, Hasharr + + n) - Hasharr;
for (int i = ; i <= n; ++i) pos[i] = lower_bound(Hasharr, Hasharr + + m, pos[i]) - Hasharr;
} void Run()
{
while (scanf("%d", &n) != EOF)
{
scanf("%s", s + );
for (int i = ; i <= n; ++i)
{
J[i] = J[i - ];
O[i] = O[i - ];
I[i] = I[i - ];
if (s[i] == 'J') ++J[i];
else if (s[i] == 'O') ++O[i];
else ++I[i];
}
for (int i = ; i <= n; ++i) pos[i] = J[i] - O[i]; Hash();
int res = ;
for (int i = ; i <= n; ++i)
{
int need = O[i] - I[i];
if (mp[pos[i]].find(need) != mp[pos[i]].end())
res = max(res, i - mp[pos[i]][need]);
else
mp[pos[i]][need] = i;
}
printf("%d\n", res);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

4260:可持久化trie+DP

 #include <bits/stdc++.h>
using namespace std; #define N 400010
int n;
int arr[N], dp[N]; int T[N];
struct TRIE
{
struct node
{
int son[], cnt;
}a[N * ]; int cnt;
void Insert(int &now, int pre, int x)
{
bitset <> b; b = x;
now = ++cnt;
a[now] = a[pre];
int root = now;
for (int i = ; i >= ; --i)
{
a[++cnt] = a[a[root].son[b[i]]];
++a[cnt].cnt;
a[root].son[b[i]] = cnt;
root = cnt;
}
}
int query(int lt, int rt, int x)
{
bitset <> b; b = x;
lt = T[lt], rt = T[rt];
int res = ;
for (int i = ; i >= ; --i)
{
int id = b[i] ^ ;
bool flag = true;
if (a[a[rt].son[id]].cnt - a[a[lt].son[id]].cnt <= )
{
flag = false;
id ^= ;
}
if (flag) res += << i;
lt = a[lt].son[id];
rt = a[rt].son[id];
}
return res;
}
}trie; void Run()
{
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%d", arr + i);
for (int i = ; i <= n; ++i) arr[i] ^= arr[i - ];
trie.cnt = ; trie.Insert(T[], T[], );
for (int i = ; i <= n; ++i) trie.Insert(T[i], T[i - ], arr[i]);
for (int i = n; i >= ; --i) dp[i] = max(dp[i + ], trie.query(i - , n, arr[i - ]));
int res = ;
for (int i = ; i <= n; ++i)
res = max(res, trie.query(, i, arr[i]) + dp[i + ]);
printf("%d\n", res);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

4291:考虑如何构造偶数

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 1000010 int n; void Run()
{
while (scanf("%d", &n) != EOF)
{
ll res = ; int cnt = , Min = 0x3f3f3f3f;
for (int i = , num; i <= n; ++i)
{
scanf("%d", &num);
if (num & )
{
++cnt;
Min = min(Min, num);
}
res += num;
}
if (cnt & ) res -= Min;
if (res == )
{
puts("NIESTETY");
continue;
}
printf("%lld\n", res); }
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ; }

4300:对每一位考虑,$b[i] And b[i - 1] != 0$ 即至少有一位都是1

 #include <bits/stdc++.h>
using namespace std; #define N 100010
int n, arr[N], Max[]; void Run()
{
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%d", arr + i);
memset(Max, , sizeof Max);
int ans = ;
for (int i = ; i <= n; ++i)
{
bitset <> b; b = arr[i];
int res = ;
for (int j = ; j >= ; --j) if (b[j])
res = max(res, Max[j]);
ans = max(res + , ans);
for (int j = ; j >= ; --j) if (b[j])
Max[j] = max(Max[j], res + );
}
printf("%d\n", ans);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

4326:二分+树剖+线段树

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 300010
#define pii pair <int, int>
int n, m;
vector <pii> G[N]; pii que[N];
struct Edge { int u, v; ll w; Edge() {} Edge(int u, int v, ll w) : u(u), v(v), w(w) {} } edge[N];
int p[N], fp[N], fa[N], deep[N], sze[N], son[N], top[N], cnt;
ll dis[N], arr[N]; void DFS(int u)
{
sze[u] = ;
for (int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i].first;
if (v == fa[u]) continue;
fa[v] = u;
deep[v] = deep[u] + ;
dis[v] = dis[u] + G[u][i].second;
DFS(v); sze[u] += sze[v];
if (!son[u] || sze[v] > sze[son[u]]) son[u] = v;
}
} void getpos(int u, int sp)
{
top[u] = sp;
p[u] = ++cnt;
fp[cnt] = u;
if (!son[u]) return;
getpos(son[u], sp);
for (int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i].first;
if (v == fa[u] || v == son[u]) continue;
getpos(v, v);
}
} struct SEG
{
int a[N << ], lazy[N << ];
void Init()
{
memset(a, , sizeof a);
memset(lazy, , sizeof lazy);
}
void pushdown(int id, int l, int r, int mid)
{
if (!lazy[id]) return;
lazy[id << ] += lazy[id];
a[id << ] += lazy[id] * (mid - l + );
lazy[id << | ] += lazy[id];
a[id << | ] += lazy[id] * (r - mid);
lazy[id] = ;
}
void pushup(int id) { a[id] = a[id << ] + a[id << | ]; }
void update(int id, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr)
{
a[id] += r - l + ;
++lazy[id];
return;
}
int mid = (l + r) >> ;
pushdown(id, l, r, mid);
if (ql <= mid) update(id << , l, mid, ql, qr);
if (qr > mid) update(id << | , mid + , r, ql, qr);
pushup(id);
}
int query(int id, int l, int r, int pos)
{
if (l == r) return a[id];
int mid = (l + r) >> ;
pushdown(id, l, r, mid);
int res = ;
if (pos <= mid) res = query(id << , l, mid, pos);
else res = query(id << | , mid + , r, pos);
pushup(id);
return res;
}
}seg; int querylca(int u, int v)
{
while (top[u] != top[v])
{
if (deep[top[u]] < deep[top[v]]) swap(u, v);
u = fa[top[u]];
}
if (deep[u] > deep[v]) swap(u, v);
return u;
} void update(int u, int v)
{
while (top[u] != top[v])
{
if (deep[top[u]] < deep[top[v]]) swap(u, v);
seg.update(, , n, p[top[u]], p[u]);
u = fa[top[u]];
}
if (u == v) return;
if (deep[u] > deep[v]) swap(u, v);
seg.update(, , n, p[son[u]], p[v]);
} bool check(ll x)
{
seg.Init(); vector <ll> vec;
for (int i = ; i <= m; ++i)
{
int u = que[i].first, v = que[i].second;
ll tot = dis[u] + dis[v] - * dis[querylca(u, v)];
if (tot <= x) continue;
update(u, v);
vec.push_back(tot);
}
ll Max = -; int tot = vec.size();
if (tot == ) return true;
for (int i = ; i <= n; ++i) if (seg.query(, , n, i) == tot)
Max = max(Max, arr[fp[i]]);
if (Max == -) return false;
for (int i = ; i < tot; ++i)
if (vec[i] - Max > x) return false;
return true;
} void Run()
{
while (scanf("%d%d", &n, &m) != EOF)
{
ll tot = ;
for (int i = , u, v, w; i < n; ++i)
{
scanf("%d%d%d", &u, &v, &w);
edge[i] = Edge(u, v, w);
G[u].push_back(pii(v, w));
G[v].push_back(pii(u, w));
tot += w;
}
for (int i = ; i <= m; ++i)
scanf("%d%d", &que[i].first, &que[i].second);
DFS(); getpos(, );
for (int i = ; i < n; ++i)
{
if (fa[edge[i].v] != edge[i].u) swap(edge[i].u, edge[i].v);
arr[edge[i].v] = edge[i].w;
}
ll l = , r = tot, res = tot;
while (r - l >= )
{
ll mid = (l + r) >> ;
if (check(mid))
{
res = mid;
r = mid - ;
}
else
l = mid + ;
}
printf("%lld\n", res);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

4397:前缀

 #include <bits/stdc++.h>
using namespace std; #define N 100010
int n, q;
int sum[][N]; void Run()
{
while (scanf("%d%d", &n, &q) != EOF)
{
memset(sum, , sizeof sum);
for (int i = , x; i <= n; ++i)
{
scanf("%d", &x);
++sum[x - ][i];
for (int j = ; j < ; ++j)
sum[j][i] += sum[j][i - ];
}
for (int i = , l, r; i <= q; ++i)
{
scanf("%d%d", &l, &r);
for (int j = ; j < ; ++j)
printf("%d%c", sum[j][r] - sum[j][l - ], " \n"[j == ]);
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

4423:对偶图+并查集 建图需要多建一圈

 #include <bits/stdc++.h>
using namespace std; #define N 1510
int n, q, S, ans;
int pos[N][N], pre[N * N]; int find(int x) { return pre[x] == ? x : pre[x] = find(pre[x]); } void Run()
{
while (scanf("%d%d", &n, &q) != EOF)
{
memset(pre, , sizeof pre);
S = (n - ) * (n - ) + ;
for (int i = ; i <= n + ; ++i) for (int j = ; j <= n + ; ++j) pos[i][j] = S;
for (int i = , tot = ; i <= n; ++i) for (int j = ; j <= n; ++j) pos[i][j] = ++tot;
char op; int a, b, x, y; ans = ;
while (q--)
{
scanf("%d%d %c", &a, &b, &op);
if (ans) scanf("%d%d %c", &a, &b, &op);
if (op == 'N') x = pos[a][b + ], y = pos[a + ][b + ];
else x = pos[a + ][b], y = pos[a + ][b + ];
if (!ans) scanf("%d%d %c", &a, &b, &op);
int fx = find(x), fy = find(y);
ans = fx == fy;
if (!ans) pre[fx] = fy;
puts(ans ? "NIE" : "TAK");
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

4448:可持久化线段树+树链剖分

 #include <bits/stdc++.h>
using namespace std; #define N 200010
#define pii pair <int, int>
int n, q;
vector <int> G[N];
int p[N], fp[N], sze[N], fa[N], deep[N], top[N], son[N], cnt; void DFS(int u)
{
sze[u] = ;
for (int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i];
if (v == fa[u]) continue;
fa[v] = u; deep[v] = deep[u] + ;
DFS(v); sze[u] += sze[v];
if (!son[u] || sze[v] > sze[son[u]]) son[u] = v;
}
} void getpos(int u, int sp)
{
top[u] = sp;
p[u] = ++cnt;
fp[cnt] = u;
if (!son[u]) return;
getpos(son[u], sp);
for (int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i];
if (v == fa[u] || v == son[u]) continue;
getpos(v, v);
}
} int T[N];
struct SEG
{
#define M N * 40
int a[M], ls[M], rs[M], cnt;
void build(int &id, int l, int r)
{
id = ++cnt;
a[id] = ;
if (l == r) return;
int mid = (l + r) >> ;
build(ls[id], l, mid);
build(rs[id], mid + , r);
}
void pushup(int id) { a[id] = a[ls[id]] + a[rs[id]]; }
void update(int &now, int pre, int l, int r, int pos)
{
now = ++cnt;
a[now] = a[pre]; ls[now] = ls[pre]; rs[now] = rs[pre];
if (l == r)
{
++a[now];
return;
}
int mid = (l + r) >> ;
if (pos <= mid) update(ls[now], ls[pre], l, mid, pos);
else update(rs[now], rs[pre], mid + , r, pos);
pushup(now);
}
int query(int now, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr) return a[now];
int mid = (l + r) >> ;
int res = ;
if (ql <= mid) res += query(ls[now], l, mid, ql, qr);
if (qr > mid) res += query(rs[now], mid + , r, ql, qr);
return res;
}
}seg; pii query(int u, int v, int c)
{
int res = ;
while (top[u] != top[v])
{
if (deep[top[u]] < deep[top[v]])
swap(u, v);
res += seg.query(T[c], , n, p[top[u]], p[u]);
u = fa[top[u]];
}
if (deep[u] > deep[v]) swap(u, v);
res += seg.query(T[c], , n, p[u], p[v]);
return pii(u, res);
} void Run()
{
while (scanf("%d", &n) != EOF)
{
for (int i = , u; i <= n; ++i)
{
scanf("%d", &u);
if (u)
{
G[u].push_back(i);
G[i].push_back(u);
}
}
DFS(); getpos(, );
seg.build(T[], , n);
scanf("%d", &q);
int op, x, y, c;
for (int i = ; i <= q; ++i)
{
scanf("%d%d", &op, &x);
if (op == ) seg.update(T[i], T[i - ], , n, p[x]);
else
{
T[i] = T[i - ];
scanf("%d%d", &y, &c);
pii res = query(x, y, max(, i - c - ));
res.first = deep[x] + deep[y] - * deep[res.first] + ;
printf("%d %d\n", res.first, res.second);
}
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

4551:树剖

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 100010 int n, q;
vector <int> G[N]; struct SEG
{
int Max[N << ];
void pushup(int id) { Max[id] = max(Max[id << ], Max[id << | ]); }
void build(int id, int l, int r)
{
Max[id] = ;
if (l == r) return;
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
}
void update(int id, int l, int r, int pos)
{
if (l == r)
{
Max[id] = pos;
return;
}
int mid = (l + r) >> ;
pos <= mid ? update(id << , l, mid, pos) : update(id << | , mid + , r, pos);
pushup(id);
}
int query(int id, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr) return Max[id];
int mid = (l + r) >> , res = ;
if (ql <= mid) res = max(res, query(id << , l, mid, ql, qr));
if (qr > mid) res = max(res, query(id << | , mid + , r, ql, qr));
return res;
}
}seg; int p[N], fp[N], sze[N], son[N], top[N], fa[N], deep[N], cnt;
void DFS(int u)
{
sze[u] = ;
for (int i = , v, len = G[u].size(); i < len; ++i)
{
v = G[u][i];
if (v != fa[u])
{
fa[v] = u;
deep[v] = deep[u] + ;
DFS(v);
sze[u] += sze[v];
if (son[u] == - || sze[v] > sze[son[u]]) son[u] = v;
}
}
} void getpos(int u, int sp)
{
top[u] = sp;
p[u] = ++cnt;
fp[cnt] = u;
if (son[u] == -) return;
getpos(son[u], sp);
for (int i = , v, len = G[u].size(); i < len; ++i)
{
v = G[u][i];
if (v != fa[u] && v != son[u])
getpos(v, v);
}
} int query(int u, int v)
{
int fu = top[u], fv = top[v];
int res = ;
while (fu != fv)
{
if (deep[fu] < deep[fv])
{
swap(fu, fv);
swap(u, v);
}
res = max(res, seg.query(, , n, p[fu], p[u]));
u = fa[fu]; fu = top[u];
}
if (deep[u] > deep[v]) swap(u, v);
res = max(res, seg.query(, , n, p[u], p[v]));
return res;
} void Run()
{
while (scanf("%d%d", &n, &q) != EOF)
{
seg.build(, , n);
memset(son, -, sizeof son);
cnt = ;
for (int i = ; i <= n; ++i) G[i].clear();
for (int i = , u, v; i < n; ++i)
{
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
DFS(); getpos(, );
seg.update(, , n, );
char op;
for (int i = , u; i <= q; ++i)
{
scanf(" %c%d", &op, &u);
if (op == 'Q') printf("%d\n", fp[query(u, )]);
else seg.update(, , n, p[u]);
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ; }

4552:二分答案+线段树 考虑把 >x 的数标为0,<x 的数标为1

 #include <bits/stdc++.h>
using namespace std; #define N 100010
int n, m, q;
int arr[N]; struct qnode
{
int op, l, r;
void scan() { scanf("%d%d%d", &op, &l, &r); }
}que[N]; struct SEG
{
int lazy[N << ], sum[N << ];
void init()
{
memset(lazy, -, sizeof lazy);
memset(sum, , sizeof sum);
}
void pushup(int id) { sum[id] = sum[id << ] + sum[id << | ]; }
void pushdown(int id, int l, int r, int mid)
{
if (lazy[id] == -) return;
lazy[id << ] = lazy[id];
sum[id << ] = lazy[id] * (mid - l + );
lazy[id << | ] = lazy[id];
sum[id << | ] = lazy[id] * (r - mid);
lazy[id] = -;
}
void update(int id, int l, int r, int ql, int qr, int val)
{
if (ql > qr) return;
if (l >= ql && r <= qr)
{
lazy[id] = val;
sum[id] = val * (r - l + );
return;
}
int mid = (l + r) >> ;
pushdown(id, l, r, mid);
if (ql <= mid) update(id << , l, mid, ql, qr, val);
if (qr > mid) update(id << | , mid + , r, ql, qr, val);
pushup(id);
}
int query(int id, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr) return sum[id];
int mid = (l + r) >> ;
pushdown(id, l, r, mid);
int res = ;
if (ql <= mid) res += query(id << , l, mid, ql, qr);
if (qr > mid) res += query(id << | , mid + , r, ql, qr);
pushup(id);
return res;
}
}seg; bool check(int x)
{
seg.init();
for (int i = ; i <= n; ++i)
seg.update(, , n, i, i, arr[i] > x);
for (int i = ; i <= m; ++i)
{
int l = que[i].l, r = que[i].r;
int cnt_one = seg.query(, , n, l, r), cnt_zero = (r - l + ) - cnt_one;
if (que[i].op == )
{
seg.update(, , n, l, l + cnt_zero - , );
seg.update(, , n, l + cnt_zero, r, );
}
else
{
seg.update(, , n, l, l + cnt_one - , );
seg.update(, , n, l + cnt_one, r, );
}
}
return !seg.query(, , n, q, q);
} void Run()
{
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%d", arr + i);
for (int i = ; i <= m; ++i) que[i].scan();
scanf("%d", &q);
int l = , r = n, res = ;
while (r - l >= )
{
int mid = (l + r) >> ;
if (check(mid))
{
res = mid;
r = mid - ;
}
else
l = mid + ;
}
printf("%d\n", res);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

4553:将一个点拆分成两个,找不等关系,CDQ分治

 #include <bits/stdc++.h>
using namespace std; #define N 100010 struct node
{
int v, Max, Min;
void scan()
{
scanf("%d", &v);
Max = Min = v;
}
void update()
{
int tmp;
scanf("%d", &tmp);
Max = max(Max, tmp);
Min = min(Min, tmp);
}
}arr[N]; struct qnode
{
int op, x, y, id;
qnode() {}
qnode(int op, int id, int x, int y) : op(op), id(id), x(x), y(y) {}
bool operator < (const qnode &r) const { return x == r.x ? (y == r.y ? (id == r.id ? op > r.op : id < r.id) : y < r.y) : x < r.x; }
}q[N << ], tq[N << ]; struct BIT
{
int a[N];
void init() { memset(a, , sizeof a); }
void update(int x, int val) { for (; x < N; x += x & -x) a[x] = max(a[x], val); }
int query(int x) { int res(); for (; x; x -= x & -x) res = max(res, a[x]); return res; }
void clear(int x) { for (; x < N; x += x & -x) a[x] = ; }
}bit; int n, m, res;
int dp[N]; void CDQ(int l, int r)
{
if (l >= r) return;
int mid = (l + r) >> ;
CDQ(l, mid);
for (int i = l; i <= r; ++i)
{
tq[i] = q[i];
if (i <= mid)
{
if (tq[i].op == )
tq[i].op = ;
else
tq[i].op = ;
}
}
sort(tq + l, tq + r + );
for (int i = l; i <= r; ++i)
{
if (!tq[i].op) bit.update(tq[i].y, dp[tq[i].id]);
else if (tq[i].op == ) dp[tq[i].id] = max(dp[tq[i].id], bit.query(tq[i].y) + );
}
for (int i = l; i <= r; ++i) if (!tq[i].op) bit.clear(tq[i].y);
CDQ(mid + , r);
} void Run()
{
while (scanf("%d%d", &n, &m) != EOF)
{
bit.init();
for (int i = ; i <= n; ++i) dp[i] = ;
for (int i = ; i <= n; ++i) arr[i].scan();
for (int i = , x; i <= m; ++i)
{
scanf("%d", &x);
arr[x].update();
}
for (int i = ; i <= n; ++i)
{
q[(i << ) - ] = qnode(, i, arr[i].Min, arr[i].v);
q[i << ] = qnode(, i, arr[i].v, arr[i].Max);
}
CDQ(, n << ); res = ;
for (int i = ; i <= n; ++i) res = max(res, dp[i]);
printf("%d\n", res);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

4999:树链剖分+线段树 (离散化后对每一个x开线段树,动态开点)

 #include <bits/stdc++.h>
using namespace std; #define N 100010
#define M 3500010 int n, m, q;
int arr[N], brr[N << ];
vector <int> G[N]; int Get(int x)
{
return lower_bound(brr + , brr + + m, x) - brr;
} struct QUE
{
int op, u, v, x;
void scan()
{
char s[];
scanf("%s", s);
if (s[] == 'Q')
{
op = ;
scanf("%d%d%d", &u, &v, &x);
brr[++m] = x;
}
else
{
op = ;
scanf("%d%d", &u, &x);
brr[++m] = x;
}
}
}que[N << ]; int top[N], num[N], deep[N], fa[N], son[N], p[N], fp[N], pos; void DFS(int u)
{
num[u] = ;
for (int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i];
if (v == fa[u]) continue;
deep[v] = deep[u] + ;
fa[v] = u;
DFS(v); num[u] += num[v];
if (son[u] == - || num[v] > num[son[u]])
son[u] = v;
}
} void getpos(int u, int sp)
{
top[u] = sp;
p[u] = ++pos;
fp[pos] = u;
if (son[u] == -) return;
getpos(son[u], sp);
for (int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i];
if (v != son[u] && v != fa[u])
getpos(v, v);
}
} struct SEG
{
int T[N << ], lson[M], rson[M], c[M], cnt; void pushup(int id)
{
c[id] = c[lson[id]] + c[rson[id]];
} void update(int &x, int l, int r, int pos, int val)
{
if (!x)
{
x = ++cnt;
lson[x] = rson[x] = c[x] = ;
}
if (l == r)
{
c[x] += val;
return;
}
int mid = (l + r) >> ;
if (pos <= mid) update(lson[x], l, mid, pos, val);
else update(rson[x], mid + , r, pos, val);
pushup(x);
} int query(int x, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr) return c[x];
int mid = (l + r) >> ;
int res = ;
if (ql <= mid) res += query(lson[x], l, mid, ql, qr);
if (qr > mid) res += query(rson[x], mid + , r, ql, qr);
return res;
} }segtree; int query(int u, int v, int x)
{
int fu = top[u], fv = top[v];
x = segtree.T[x];
int res = ;
while (fu != fv)
{
if (deep[fu] < deep[fv])
{
swap(u, v);
swap(fu, fv);
}
res += segtree.query(x, , n, p[fu], p[u]);
u = fa[fu];
fu = top[u];
}
if (deep[u] > deep[v]) swap(u, v);
res += segtree.query(x, , n, p[u], p[v]);
return res;
} void Run()
{
while (scanf("%d%d", &n, &q) != EOF)
{
m = ; fa[] = ; deep[] = ; pos = ;
memset(son, -, sizeof son);
for (int i = ; i <= n; ++i) scanf("%d", arr + i), brr[++m] = arr[i];
for (int i = , u, v; i < n; ++i)
{
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
} DFS(); getpos(, );
for (int i = ; i <= q; ++i) que[i].scan();
sort(brr + , brr + + m);
m = unique(brr + , brr + + m) - brr - ;
for (int i = ; i <= n; ++i) arr[i] = Get(arr[i]);
for (int i = ; i <= q; ++i) que[i].x = Get(que[i].x);
for (int i = ; i <= n; ++i) segtree.update(segtree.T[arr[i]], , n, p[i], );
for (int i = ; i <= q; ++i)
{
if (que[i].op == )
printf("%d\n", query(que[i].u, que[i].v, que[i].x));
else
{
int u = que[i].u, x = que[i].x;
segtree.update(segtree.T[arr[u]], , n, p[u], -);
arr[u] = x;
segtree.update(segtree.T[arr[u]], , n, p[u], );
}
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

5204:水。

 #include <bits/stdc++.h>
using namespace std; #define N 100010
int t, n, m, a[N], b[N], cnt[N]; void Hash()
{
for (int i = ; i <= n; ++i) b[i] = a[i];
sort(b + , b + + n);
m = unique(b + , b + + n) - b - ;
for (int i = ; i <= n; ++i) a[i] = lower_bound(b + , b + + m, a[i]) - b;
} bool ok()
{
for (int i = ; i <= m; ++i) if (cnt[i] != cnt[i - ])
return true;
return false;
} void Run()
{
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
memset(cnt, , sizeof cnt);
for (int i = ; i <= n; ++i) scanf("%d", a + i); Hash();
for (int i = ; i <= n; ++i) ++cnt[a[i]];
if (!ok()) puts("-1");
else
{
int Max = *max_element(cnt + , cnt + + m);
int tot = ;
for (int i = ; i <= m; ++i) if (cnt[i] == Max)
++tot;
printf("%d\n", tot);
for (int i = , j = ; i <= m; ++i) if (cnt[i] == Max)
printf("%d%c", b[i], " \n"[(++j) == tot]);
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

5293:lca+前缀点权和

 #include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 300010
const ll MOD = (ll);
int n, q;
vector <int> G[N];
int p[N], fp[N], deep[N], fa[N], sze[N], top[N], son[N], cnt;
ll dis[N][]; void DFS(int u)
{
sze[u] = ;
for (int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i];
if (v == fa[u]) continue;
fa[v] = u; deep[v] = deep[u] + ;
dis[v][] = deep[v];
dis[v][] = ;
for (int i = ; i <= ; ++i)
dis[v][i] = (dis[v][i - ] * deep[v]) % MOD;
for (int i = ; i <= ; ++i)
dis[v][i] = (dis[v][i] + dis[u][i]) % MOD;
DFS(v); sze[u] += sze[v];
if (son[u] == - || sze[v] > sze[son[u]]) son[u] = v;
}
} void getpos(int u, int sp)
{
top[u] = sp;
p[u] = ++cnt;
fp[cnt] = u;
if (son[u] == -) return;
getpos(son[u], sp);
for (int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i];
if (v == fa[u] || v == son[u]) continue;
getpos(v, v);
}
} int querylca(int u, int v)
{
while (top[u] != top[v])
{
if (deep[top[u]] < deep[top[v]])
swap(u, v);
u = fa[top[u]];
}
if (deep[u] > deep[v]) swap(u, v);
return u;
} void Init()
{
for (int i = ; i <= n; ++i) G[i].clear();
memset(son, -, sizeof son);
cnt = ; dis[][] = ;
} void Run()
{
while (scanf("%d", &n) != EOF)
{
Init();
for (int i = , u, v; i < n; ++i)
{
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
DFS(); getpos(, );
scanf("%d", &q);
for (int i = , u, v, k; i <= q; ++i)
{
scanf("%d%d%d", &u, &v, &k);
int lca = querylca(u, v);
printf("%lld\n", (dis[u][k] + dis[v][k] - dis[lca][k] - dis[fa[lca]][k] + * MOD) % MOD);
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

5301:莫队

 #include <bits/stdc++.h>
using namespace std; #define N 100010
#define unit 450
#define ll long long struct qnode
{
int l, r, id;
void scan(int id)
{
scanf("%d%d", &l, &r); --l;
this->id = id;
}
bool operator < (const qnode &r) const
{
int posl = l / unit, posr = r.l / unit;
return posl < posr || posl == posr && this->r < r.r;
}
}que[N];
int n, m, k, a[N], ans[N], cnt[N];
ll res; void add(int x)
{
if (x == -) return;
int pos = a[x] ^ k;
res += cnt[pos];
++cnt[a[x]];
} void del(int x)
{
if (x == -) return;
int pos = a[x] ^ k;
--cnt[a[x]];
res -= cnt[pos];
} void Run()
{
while (scanf("%d%d%d", &n, &m, &k) != EOF)
{
memset(cnt, , sizeof cnt);
for (int i = ; i <= n; ++i) scanf("%d", a + i), a[i] ^= a[i - ];
for (int i = ; i <= m; ++i) que[i].scan(i);
sort(que + , que + + m); cnt[] = ;
for (int i = , l = , r = ; i <= m; ++i)
{
for (; r < que[i].r; ++r) add(r + );
for (; r > que[i].r; --r) del(r);
for (; l < que[i].l; ++l) del(l);
for (; l > que[i].l; --l) add(l - );
ans[que[i].id] = res;
}
for (int i = ; i <= m; ++i) printf("%d\n", ans[i]);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

5313:循环节

 #include <bits/stdc++.h>
using namespace std; int f[]; void Run()
{
f[] = , f[] = ;
for (int i = ; i < ; ++i) f[i] = (f[i - ] + f[i - ]) % ;
int q, x;
while (scanf("%d", &q) != EOF)
{
while (q--)
{
scanf("%d", &x);
printf("%d\n", f[(x - ) % + ]);
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

5338:树剖+可持久化Trie

 #include <bits/stdc++.h>
using namespace std; #define N 100010
int n, q;
int arr[N];
vector <int> G[N];
int p[N], fp[N], lp[N], rp[N], sze[N], son[N], top[N], deep[N], fa[N], cnt; void DFS(int u)
{
sze[u] = ;
for (int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i];
if (v == fa[u]) continue;
fa[v] = u; deep[v] = deep[u] + ;
DFS(v); sze[u] += sze[v];
if (son[u] == - || sze[v] > sze[son[u]]) son[u] = v;
}
} void getpos(int u, int sp)
{
top[u] = sp;
p[u] = ++cnt;
fp[cnt] = u;
lp[u] = cnt;
if (son[u] == -)
{
rp[u] = cnt;
return;
}
getpos(son[u], sp);
for (int i = , len = G[u].size(); i < len; ++i)
{
int v = G[u][i];
if (v == fa[u] || v == son[u]) continue;
getpos(v, v);
}
rp[u] = cnt;
} int T[N];
struct TRIE
{
struct node
{
int son[], cnt;
node() { memset(son, , sizeof son); cnt = ; }
}a[N * ]; int cnt;
void Init()
{
a[] = node();
cnt = ;
}
void Insert(int now, int pre, int val)
{
bitset <> b; b = val;
T[now] = ++cnt;
pre = T[pre];
now = T[now];
a[now] = a[pre];
for (int i = ; i >= ; --i)
{
a[++cnt] = a[a[now].son[b[i]]];
++a[cnt].cnt;
a[now].son[b[i]] = cnt;
now = cnt;
}
}
int query(int lt, int rt, int val)
{
bitset <> b; b = val;
lt = T[lt], rt = T[rt];
int res = ;
for (int i = ; i >= ; --i)
{
int id = b[i] ^ ;
bool flag = true;
if (a[a[rt].son[id]].cnt - a[a[lt].son[id]].cnt <= )
{
id ^= ;
flag = false;
}
if (flag) res += << i;
rt = a[rt].son[id];
lt = a[lt].son[id];
}
return res;
}
}trie; int query(int u, int v, int x)
{
int res = ;
while (top[u] != top[v])
{
if (deep[top[u]] < deep[top[v]])
swap(u, v);
res = max(res, trie.query(p[top[u]] - , p[u], x));
u = fa[top[u]];
}
if (deep[u] > deep[v]) swap(u, v);
res = max(res, trie.query(p[u] - , p[v], x));
return res;
} void Init()
{
memset(son, -, sizeof son);
trie.Init();
} void Run()
{
while (scanf("%d%d", &n, &q) != EOF)
{
Init();
for (int i = ; i <= n; ++i) scanf("%d", arr + i);
for (int i = , u, v; i < n; ++i)
{
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
DFS(); getpos(, );
for (int i = ; i <= n; ++i) trie.Insert(i, i - , arr[fp[i]]);
for (int i = , op, x, y, z; i <= q; ++i)
{
scanf("%d%d%d", &op, &x, &y);
if (op == ) printf("%d\n", trie.query(lp[x] - , rp[x], y));
else
{
scanf("%d", &z);
printf("%d\n", query(x, y, z));
}
}
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run();
return ;
}

end.

BZOJ 一句话题解的更多相关文章

  1. bzoj一句话题解

    发现好多人都在搞这个...本人也想来试试(Solved刚到70就搞这个靠不靠谱啊喂).会更新的.嗯. 1000-1029 1000 A+B problem (这个还需要一句话吗?). 1001 狼抓兔 ...

  2. BZOJ一句话

    一句话题解集合. 1061: [Noi2008]志愿者招募 单纯形,运用对偶原理转化过来,变成标准形然后单纯性裸上即可. #include<cmath> #include<cstdi ...

  3. Bzoj 近期题目一句话题解

    目录 Bzoj 近期题目题解 1000: A+B Problem (模拟) 1008: [HNOI2008]越狱 (容斥) 1012: [JSOI2008]最大数maxnumber (线段树) 103 ...

  4. LOJ 一本通一句话题解系列:

    第一部分 基础算法 第 1 章 贪心算法 1):「一本通 1.1 例 1」活动安排:按照结束时间排序,然后扫一遍就可以了. 2):「一本通 1.1 例 2」种树:首先要尽量的往区间重叠的部分种树,先按 ...

  5. BZOJ 3732 题解

    3732: Network Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1…N. 图中有M条边 (1 <= M <= 30,000) ...

  6. BZOJ1000-1099板刷计划+一句话题解 73/100

    1000-1009 1000A+B Problem 这个还要写??? 1001 狼抓兔子 平面图最小割转化为对偶图最短路 #include<bits/stdc++.h> #define i ...

  7. bzoj 2669 题解(状压dp+搜索+容斥原理)

    这题太难了...看了30篇题解才整明白到底咋回事... 核心思想:状压dp+搜索+容斥 首先我们分析一下,对于一个4*7的棋盘,低点的个数至多只有8个(可以数一数) 这样的话,我们可以进行一个状压,把 ...

  8. noip做题记录+挑战一句话题解?

    因为灵巧实在太弱辽不得不做点noip续下命QQAQQQ 2018 积木大赛/铺设道路 傻逼原题? 然后傻逼的我居然检查了半天是不是有陷阱最后花了差不多一个小时才做掉我做过的原题...真的傻逼了我:( ...

  9. LeetCode一句话题解

    深度优先搜索 人生经验 1. 需要输出所有解.并由于元素集有重复元素,要求返回的结果需要去重的情况,可考虑使用值对应数量的map,然后分别考虑依次取不同数量该值的可能. LeetCode39 题目:给 ...

随机推荐

  1. website 合集

    1. oracle  http://asktom.oracle.com ( 英文 ) http://itpub.net ( 中文 ) https://www.oracle.com/communitie ...

  2. php 路由实现

    因为有小的业务逻辑比较复杂,orm用起来很麻烦,但是多入口又不好控制,每个页面都去包含,多了就迷了,所以就只写了个路由,加了个防注入 封装增删改查好无聊,直接封装业务逻辑,为业务而开发,业务逻辑里是面 ...

  3. 第一百六十一节,封装库--JavaScript,完整封装库文件

    封装库--JavaScript,完整封装库文件 /** *feng_zhuang_ku_1.0版本,js封装库,2016/12/29日:林贵秀 **/ /** 前台调用 * 每次调用$()创建库对象, ...

  4. centos7 安装kvm虚拟机

    准备工作 centos7 光盘文件 物理机(>=4 Cores; >= 4GB memory; >= 40G disk size) 参考文档:KVM Virtualization i ...

  5. centos6.5安装apache2

    参考 http://my.oschina.net/u/593517/blog/340289 http://blog.csdn.net/hkmaike/article/details/9732177

  6. html5 webwork

    在Web开发的时候经常会遇到浏览器不响应事件进入假死状态,甚至弹出“脚本运行时间过长“的提示框,如果出现这种情况说明你的脚本已经失控了. 一个浏览器至少存在三个线程:js引擎线程(处理js).GUI渲 ...

  7. drupal7使用数据库api db_query需要注意的地方

    写自定义module时候需要从数据库检索数据,用到了数据库的api,用了下面的sql: $record = db_query("SELECT 'sampledate', 'time' FRO ...

  8. iOS-Pods里三方文件导入找不到头文件

    解决办法: 在target 里面 选择 build setting 搜索User Header Search Paths 然后 里面添加一条 ${SRCROOT}     recursive//后面填 ...

  9. Win10下Hyper-V设置网络连接

    具体方法如下. 1.点击虚拟交换机管理 2.创建虚拟交换机 选择内部 3.选择链接类型

  10. boost::archive::binary_iarchive

    #include <iostream> #include <string> #include <sstream> #include <vector> # ...