> _t;
while (_t--) {
solve();
}
return 0;
}
带权并查集
P2024 [NOI2001] 食物链
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
const LL N = 5e4 + 10;
const LL M = 1e5 + 10;
int fa[N], cnt[N],va[N];
int n, m,ans=0;
struct node {
int a, b, c;
bool operator<(const node x)const {
return c > x.c;
}
}th[M];
void init() {
for (int i = 1; i <= n; ++i) {
fa[i] = i;
cnt[i] = 1;
va[i] = 0;
}
}
int find(int a) {
if (a == fa[a]) return a;
int temp = find(fa[a]);
va[a] = (va[a] + va[fa[a]]) % 3;
fa[a] = temp;
return fa[a];
}
void merge(int a, int b,int op) {
int aa = find(a), bb = find(b);
if (aa == bb) return;
if (cnt[aa] > cnt[bb]) {
fa[bb] = aa;
va[bb] = (va[a] - va[b] -op+ 3) % 3;
}
else {
if (cnt[aa] == cnt[bb]) cnt[bb]++;
fa[aa] = bb;
va[aa] = (va[b] - va[a] +op+ 3) % 3;
}
}
int query(int a, int b) {
int aa = find(a), bb = find(b);
if (aa != bb) return -1;
else return (va[a] - va[b] + 3) % 3;
}
void solve() {
cin >> n >> m;
init();
for (int i = 0; i < m; ++i) {
int op, a, b;
cin >> op >> a >> b;
op--;
if (a > n || b > n || op == 1 && a == b||query(a,b)!=op&&query(a,b)!=-1) ans++;
else merge(a, b, op);
}
cout << ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin >> _t;
while (_t--) {
solve();
}
return 0;
}
可持久化并查集
P3402 可持久化并查集
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 2e5 + 10;
struct tree {
int l, r, fa, siz;
}tr[N << 5];
int n, m, cur;
int cnt, root[N];
int build(int l, int r) {
int x = ++cnt;
if (l == r) {
tr[x].fa = l;
tr[x].siz = 1;
return x;
}
int mid = l + r >> 1;
tr[x].l = build(l, mid);
tr[x].r = build(mid + 1, r);
return x;
}
int modifyfa(int x, int l, int r, int a, int b) {
int u = ++cnt;
tr[u].l = tr[x].l, tr[u].r = tr[x].r;
if (l == r) {
tr[u].fa = b;
tr[u].siz = tr[x].siz;
return u;
}
int mid = l + r >> 1;
if (a <= mid) tr[u].l = modifyfa(tr[x].l, l, mid, a, b);
else tr[u].r = modifyfa(tr[x].r, mid + 1, r, a, b);
return u;
}
int modifysiz(int x, int l, int r, int a, int b) {
int u = ++cnt;
tr[u].l = tr[x].l, tr[u].r = tr[x].r;
if (l == r) {
tr[u].siz = b;
tr[u].fa = tr[x].fa;
return u;
}
int mid = l + r >> 1;
if (a <= mid) tr[u].l = modifysiz(tr[x].l, l, mid, a, b);
else tr[u].r = modifysiz(tr[x].r, mid + 1, r, a, b);
return u;
}
int queryfa(int x, int l, int r, int k) {
if (l == r) return tr[x].fa;
int mid = l + r >> 1;
if (k <= mid) return queryfa(tr[x].l, l, mid, k);
else return queryfa(tr[x].r, mid + 1, r, k);
}
int querysiz(int x, int l, int r, int k) {
if (l == r) return tr[x].siz;
int mid = l + r >> 1;
if (k <= mid) return querysiz(tr[x].l, l, mid, k);
else return querysiz(tr[x].r, mid + 1, r, k);
}
int find(int x) {
int f = queryfa(root[cur], 1, n, x);
if (f == x) return f;
else return find(f);
}
void merge(int a, int b) {
a = find(a), b = find(b);
if (a == b) {
root[cur + 1] = root[cur];
return;
}
int siz1 = querysiz(root[cur], 1, n, a), siz2 = querysiz(root[cur], 1, n, b);
if (siz1 < siz2) {
root[cur + 1] = modifyfa(root[cur], 1, n, a, b);
root[cur + 1] = modifysiz(root[cur + 1], 1, n, b, siz1 + siz2);
}
else {
root[cur + 1] = modifyfa(root[cur], 1, n, b, a);
root[cur + 1] = modifysiz(root[cur + 1], 1, n, a, siz1 + siz2);
}
}
void solve() {
cin >> n >> m;
root[0] = build(1, n);
for (int i = 1; i <= m; ++i) {
int op;
cin >> op;
if (op == 1) {
int a, b;
cin >> a >> b;
merge(a, b);
}
else if (op == 2) {
int k;
cin >> k;
root[cur + 1] = root[k];
}
else {
int a, b;
cin >> a >> b;
cout << (find(a) == find(b)) << '\n';
root[cur + 1] = root[cur];
}
cur++;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
树状数组
P3374 【模板】树状数组 1
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
const LL N = 5e5 + 10;
int n, m;
int c[N];
inline int lowbit(int x) {
return x & -x;
}
void add(int x, int y) {
for (; x <= n; x += lowbit(x)) c[x] += y;
}
int sum(int x) {
int res = 0;
for (; x; x -= lowbit(x)) res += c[x];
return res;
}
void solve() {
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
int x;
cin >> x;
add(i, x);
}
for (int i = 0; i < m; ++i) {
int op,x,y;
cin >> op>>x>>y;
if (op == 1) add(x, y);
else cout << sum(y) - sum(x-1) << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t
while (_t--) {
solve();
}
return 0;
}
P1908 逆序对
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
const ll N = 5e5 + 10;
int n, m;
int a[N], b[N], c[N];
ll ans = 0;
inline int lowbit(int x) {
return x & -x;
}
void add(int x, int k) {
for (; x <= m; x += lowbit(x)) c[x] += k;
}
void query(int x) {
for (; x; x -= lowbit(x)) ans += c[x];
}
void solve() {
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
b[i] = a[i];
}
sort(b + 1, b + n + 1);
m = unique(b + 1, b + n + 1) - b - 1;
for (int i = 1; i <= n; ++i) {
a[i] = lower_bound(b + 1, b + m + 1, a[i]) - b;
}
for (int i = n; i > 0; --i) {
add(a[i], 1);
query(a[i] - 1);
}
cout << ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t
while (_t--) {
solve();
}
return 0;
}
线段树
P3372 【模板】线段树 1
时间
空间
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
const LL N = 1e5 + 10;
LL sum[4 * N], tag[4 * N], sze[4 * N], a[N];
void pushtag(int x, LL k) {
sum[x] += sze[x] * k;
tag[x] += k;
}
void pushdown(int x) {
if (tag[x]) {
pushtag(x << 1, tag[x]);
pushtag(x << 1 | 1, tag[x]);
tag[x] = 0;
}
}
void pushup(int x) {
sum[x] = sum[x << 1] + sum[x << 1 | 1];
sze[x] = sze[x << 1] + sze[x << 1 | 1];
}
void build(int x, int l, int r) {
if (l == r) {
sum[x] = a[l];
sze[x] = 1;
return;
}
int mid = (l + r) >> 1;
build(x << 1, l, mid);
build(x << 1 | 1, mid + 1, r);
pushup(x);
}
void add(int x, int l, int r, int ql, int qr, LL k) {
if (ql <= l && qr >= r) {
pushtag(x, k);
return;
}
pushdown(x);
int mid = (l + r) >> 1;
if (ql <= mid) add(x << 1, l, mid, ql, qr, k);
if (qr > mid) add(x << 1 | 1, mid + 1, r, ql, qr, k);
pushup(x);
}
LL query(int x, int l, int r, int ql, int qr) {
if (ql <= l && qr >= r) return sum[x];
pushdown(x);
int mid = (l + r) >> 1;
LL ans = 0;
if (ql<=mid) ans += query(x << 1, l, mid, ql, qr);
if (qr > mid) ans += query(x << 1 | 1, mid + 1, r, ql, qr);
return ans;
}
void solve() {
int n, m;
cin >> n>>m;
for (int i = 1; i <= n; ++i) cin >> a[i];
build(1, 1, n);
for (int i = 1; i <= m; ++i) {
int op, x, y;
cin >> op >> x >> y;
if (op == 1) {
LL k;
cin >> k;
add(1, 1, n, x, y, k);
}
else cout << query(1, 1, n, x, y) << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) solve();
return 0;
}
线段树区间合并
hdu1540 Tunnel Warfare
参考博客
#include
#define rep(i, n) for (int i = 1; i <= (n); ++i)
using namespace std;
typedef long long ll;
const int N = 5e4 + 10;
struct node {
int l, r;
int lmax, rmax; //左右最大连续长度
}t[N << 2];
void pushup(node& p, node& l, node& r) { //区间合并
p.lmax = l.lmax + (l.lmax == l.r - l.l + 1 ? r.lmax : 0);
p.rmax = r.rmax + (r.rmax == r.r - r.l + 1 ? l.rmax : 0);
}
void pushup(int x) { pushup(t[x], t[x << 1], t[x << 1 | 1]); }
void build(int l, int r, int x = 1) {
t[x] = { l, r, 1, 1 };
if (l == r) return;
int mid = l + r >> 1;
build(l, mid, x << 1), build(mid + 1, r, x << 1 | 1);
pushup(x);
}
void modify(int a, int c, int x = 1) {
if (t[x].l == t[x].r) {
t[x].lmax = t[x].rmax = c;
return;
}
int mid = t[x].l + t[x].r >> 1;
modify(a, c, x << 1 | (a > mid));
pushup(x);
}
int ask(int a, int x = 1) {
if (t[x].l == t[x].r) return t[x].lmax;
int mid = t[x].l + t[x].r >> 1;
if (a <= mid) { //表明a在左子树, 看看左子树右连续区间是否包含a点
node& op = t[x << 1];
if (a >= op.r - op.rmax + 1) return op.rmax + t[x << 1 | 1].lmax;
return ask(a, x << 1); //不包含a
}
else { //表明a在右子树, 看看右子树左连续区间是否包含a点
node& op = t[x << 1 | 1];
if (a <= op.l + op.lmax - 1) return op.lmax + t[x << 1].rmax;
return ask(a, x << 1 | 1); //不包含a
}
}
int main(){
int n, m;
while (~scanf("%d %d", &n, &m)) {
stack st; //记录最后被删除的点
build(1, n);
rep(i, m) {
char s[2]; scanf("%s", s);
if (s[0] == 'D') {
int a; scanf("%d", &a);
modify(a, 0);
st.push(a);
}
else if (s[0] == 'Q') {
int a; scanf("%d", &a);
printf("%d\n", ask(a));
}
else modify(st.top(), 1), st.pop();
}
}
return 0;
}
吉司机线段树
P6242 【模板】线段树 3
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
#define P pair
const double eps = 1e-8;
const LL N = 2e6 + 10;
const LL INF = 1e10;
LL n, m, a[N], sum[N], maxn[N], sze[N], se[N], maxt[N], maxh[N], tag1[N], tag2[N], tag3[N], tag4[N];
LL read() {
LL res = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch>'9') { if (ch == '-') { f = -1; } ch = getchar(); }
while (ch >= '0' && ch <= '9') { res = res * 10 + ch - '0', ch = getchar(); }
return f * res;
}
void pushtag(int x, LL k1, LL k2, LL k3, LL k4) {
sum[x] += k1 * maxt[x] + k3 * (sze[x] - maxt[x]);
maxh[x] = max(maxh[x], maxn[x] + k2);
tag2[x] = max(tag2[x], tag1[x] + k2);
tag1[x] += k1;
maxn[x] += k1;
tag4[x] = max(tag4[x], tag3[x] + k4);
tag3[x] += k3;
if (se[x] != -INF) se[x] += k3;
}
void pushdown(int x) {
LL temp = max(maxn[x << 1], maxn[x << 1 | 1]);
if (temp == maxn[x << 1]) pushtag(x << 1, tag1[x], tag2[x], tag3[x], tag4[x]);
else pushtag(x << 1, tag3[x], tag4[x], tag3[x], tag4[x]);
if (temp == maxn[x << 1 | 1]) pushtag(x << 1 | 1, tag1[x], tag2[x], tag3[x], tag4[x]);
else pushtag(x << 1 | 1, tag3[x], tag4[x], tag3[x], tag4[x]);
tag1[x] = tag2[x] = tag3[x] = tag4[x] = 0;
}
void pushup(int x) {
sum[x] = sum[x << 1] + sum[x << 1 | 1];
sze[x] = sze[x << 1] + sze[x << 1 | 1];
maxn[x] = max(maxn[x << 1], maxn[x << 1 | 1]);
maxh[x] = max(maxh[x << 1], maxh[x << 1 | 1]);
if (maxn[x << 1] == maxn[x << 1 | 1]) {
maxt[x] = maxt[x << 1] + maxt[x << 1 | 1];
se[x] = max(se[x << 1], se[x << 1 | 1]);
}
else {
se[x] = max(min(maxn[x << 1], maxn[x << 1 | 1]), max(se[x << 1], se[x << 1 | 1]));
maxt[x] = maxn[x << 1] > maxn[x << 1 | 1] ? maxt[x << 1] : maxt[x << 1 | 1];
}
}
void build(int x, int l, int r) {
if (l == r) {
sum[x] = maxn[x] = maxh[x] = a[l];
sze[x] = maxt[x] = 1;
se[x] = -INF;
return;
}
int mid = (l + r) >> 1;
build(x << 1, l, mid);
build(x << 1 | 1, mid + 1, r);
pushup(x);
}
void add(int x, int l, int r, int ql, int qr, LL k) {
if (ql <= l && qr >= r) {
pushtag(x, k, k, k, k);
return;
}
pushdown(x);
int mid = (l + r) >> 1;
if (ql <= mid) add(x << 1, l, mid, ql, qr, k);
if (qr > mid)add(x << 1 | 1, mid + 1, r, ql, qr, k);
pushup(x);
}
void modify(int x, int l, int r, int ql, int qr, LL k) {
if (k >= maxn[x]) return;
if (ql <= l && qr >= r && kse[x]) {
pushtag(x, k - maxn[x], k - maxn[x], 0, 0);
return;
}
pushdown(x);
int mid = (l + r) >> 1;
if (ql <= mid) modify(x << 1, l, mid, ql, qr, k);
if (qr > mid) modify(x << 1 | 1, mid + 1, r, ql, qr, k);
pushup(x);
}
LL querysum(int x, int l, int r, int ql, int qr) {
if (ql <= l && qr >= r) return sum[x];
LL ans = 0;
pushdown(x);
int mid = (l + r) >> 1;
if (ql <= mid) ans += querysum(x << 1, l, mid, ql, qr);
if (qr > mid) ans += querysum(x << 1 | 1, mid + 1, r, ql, qr);
return ans;
}
LL querymaxa(int x, int l, int r, int ql, int qr) {
if (ql <= l && qr >= r) return maxn[x];
LL ans = -INF;
pushdown(x);
int mid = (l + r) >> 1;
if (ql <= mid) ans = max(ans, querymaxa(x << 1, l, mid, ql, qr));
if (qr > mid) ans = max(ans, querymaxa(x << 1 | 1, mid + 1, r, ql, qr));
return ans;
}
LL querymaxb(int x, int l, int r, int ql, int qr) {
if (ql <= l && qr >= r) return maxh[x];
LL ans = -INF;
pushdown(x);
int mid = (l + r) >> 1;
if (ql <= mid) ans = max(ans, querymaxb(x << 1, l, mid, ql, qr));
if (qr > mid) ans = max(ans, querymaxb(x << 1 | 1, mid + 1, r, ql, qr));
return ans;
}
void solve() {
n = read(), m = read();
for (int i = 1; i <= n; ++i) a[i] = read();
build(1, 1, n);
for (int i = 1; i <= m; ++i) {
int op = read(), l = read(), r = read();
if (op == 1) {
LL k = read();
add(1, 1, n, l, r, k);
}
else if (op == 2) {
LL k = read();
modify(1, 1, n, l, r, k);
}
else if (op == 3) cout << querysum(1, 1, n, l, r) << '\n';
else if (op == 4) cout << querymaxa(1, 1, n, l, r) << '\n';
else cout << querymaxb(1, 1, n, l, r) << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
李超线段树
P4097 [HEOI2013] Segment
扫描线(面积)
P5490 【模板】扫描线
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
#define P pair
const double eps = 1e-8;
const LL INF = 1e18;
const LL N = 1e5 + 10;
struct Line {
LL xl, xr, y;
int inout;
Line(LL xl,LL xr,LL y,int inout):xl(xl),xr(xr),y(y),inout(inout){}
Line(){}
bool operator<(const Line a)const {
return y < a.y;
}
}line[2 * N];
LL xx[2 * N], len[8 * N], tag[8 * N],ans=0;
int cnt = 0, num = 0;
void pushup(int x, int l,int r) {
if (tag[x]) len[x] = xx[r+1] - xx[l];
else if (l == r) len[x] = 0;
else len[x] = len[x << 1] + len[x << 1 | 1];
}
void modify(int x, int l, int r, int ql, int qr,int inout) {
if (l >= ql && r <= qr) {
tag[x] += inout;
pushup(x,l,r);
return;
}
int mid = (l + r) >> 1;
if (ql <= mid) modify(x << 1, l, mid, ql, qr, inout);
if (qr > mid) modify(x << 1 | 1, mid+1, r, ql, qr, inout);
pushup(x,l,r);
}
void solve() {
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
LL x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
line[++cnt] = Line(x1, x2, y1, 1);
xx[cnt] = x1;
line[++cnt] = Line(x1, x2, y2, -1);
xx[cnt] = x2;
}
sort(line + 1, line + cnt + 1);
sort(xx + 1, xx + cnt + 1);
num = unique(xx + 1, xx + cnt + 1) - (xx + 1);
for (int i = 1; i <= cnt; ++i) {
ans += len[1] * (line[i].y - line[i-1].y);
int ql = lower_bound(xx + 1, xx + num + 1, line[i].xl) - xx;
int qr = lower_bound(xx + 1, xx + num + 1, line[i].xr) - xx-1;
modify(1, 1, num-1, ql, qr,line[i].inout);
}
cout << ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
扫描线(周长)
hdu1828 Picture
参考博客
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
#define mem(a,x) memset(a,x,sizeof(a))
#define ls i<<1
#define rs i<<1|1
#define m(i) ((q[i].l + q[i].r)>>1)
const int N = 5e3 + 10;
const int M = 2e4 + 10;
const int inf = 1<<29;
struct Edge//扫描线{
int l,r;//左右端点的横坐标
int h;//这条线的高度,即纵坐标
int f;//标记这条边是上边(-1)还是下边(1)
}e[2*N];
bool cmp(Edge a,Edge b){
return a.h < b.h;//高度从小到大排,扫描线自下而上扫
}
struct Node{
int l,r;//该节点代表的线段的左右端点坐标
int len;//这个区间被覆盖的长度
int s;//表示这个区间被重复覆盖了几次
bool lc,rc;//表示这个节点左右两个端点是否被覆盖(0表示没有被覆盖,1表示有被覆盖)
int num;//这个区间有多少条线段(这个区间被多少条线段覆盖)
//len用来计算横线 num用来计算竖线
}q[4*M];
void pushup(int i){//区间合并
if (q[i].s){//整个区间被覆盖
q[i].len = q[i].r - q[i].l + 1;
q[i].lc = q[i].rc = 1;
q[i].num = 1;
}
else if (q[i].l == q[i].r){//这是一个点而不是一条线段
q[i].len = 0;
q[i].lc = q[i].rc = 0;
q[i].num = 0;
}
else{//是一条没有整个区间被覆盖的线段,合并左右子的信息
q[i].len = q[ls].len + q[rs].len ;//长度之和
q[i].lc = q[ls].lc;q[i].rc = q[rs].rc;//和左儿子共左端点,和右儿子共右端点
q[i].num = q[ls].num + q[rs].num - (q[ls].rc&q[rs].lc);
//如果左子的右端点和右子的左端点都被覆盖了
}
}
void build (int i,int l,int r){
q[i].l = l,q[i].r = r;
q[i].s = q[i].len = 0;
q[i].lc = q[i].rc = q[i].num = 0;
if (l == r) return;
int mid = m(i);
build(ls,l,mid);
build(rs,mid+1,r);
}
void update(int i,int l,int r,int xx){
if (l == q[i].l && q[i].r == r){
q[i].s += xx;
pushup(i);
return;
}
int mid = m(i);
if (r <= mid) update(ls,l,r,xx);
else if (l > mid) update(rs,l,r,xx);
else{
update(ls,l,mid,xx);
update(rs,mid+1,r,xx);
}
pushup(i);
}
int main(){
int n;
while (cin>>n){
int x1,x2,y1,y2,mx = -inf,mn = inf;
int tot = 0;
for (int i = 0;i < n;++i){
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
mx = max(mx,max(x1,x2));
mn = min(mn,min(x1,x2));
Edge & t1 = e[tot];Edge & t2 = e[tot+1];
t1.l = t2.l = x1,t1.r = t2.r = x2;
t1.h = y1;t1.f = 1;
t2.h = y2;t2.f = -1;
tot += 2;
}
sort(e,e+tot,cmp);
//数据小可以不离散化
int ans = 0;//计算周长
int last = 0;//保存上一次的总区间的被覆盖的长度
build(1,mn,mx-1);
//每两条横线之间才会有竖线
for (int i = 0;i < tot;++i){
update(1,e[i].l,e[i].r-1,e[i].f);//根据扫描线更新
//横线:现在这次总区间被覆盖的程度和上一次总区间被覆盖的长度之差的绝对值
ans += abs(q[1].len - last);
//竖线:[下一条横线的高度-现在这条横线的高度]*2*num
ans += (e[i+1].h - e[i].h)*2*q[1].num;
last = q[1].len;//每次都要更新上一次总区间覆盖的长度
}
printf("%d\n",ans);
}
return 0;
}
线段树套线段树
hdu1823 Luck and Love
参考博客
#include
using namespace std;
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
int n, s[1005][4005];
void subBuild(int xrt, int l, int r, int rt) {
s[xrt][rt] = -1;
if(l != r) {
int m = l + r >> 1;
subBuild(xrt, lson);
subBuild(xrt, rson);
}
}
void build(int l, int r, int rt) {
subBuild(rt, 0, n, 1);
if(l != r) {
int m = l + r >> 1;
build(lson);
build(rson);
}
}
void subUpdate(int xrt, int y, int c, int l, int r, int rt) {
if(l == r && l == y) s[xrt][rt] = max(s[xrt][rt], c);
else {
int m = l + r >> 1;
if(y <= m) subUpdate(xrt, y, c, lson);
else subUpdate(xrt, y, c, rson);
s[xrt][rt] = max(s[xrt][rt << 1], s[xrt][rt << 1 | 1]);
}
}
void update(int x, int y, int c, int l, int r, int rt) {
subUpdate(rt, y, c, 0, n, 1);
if(l != r) {
int m = l + r >> 1;
if(x <= m) update(x, y, c, lson);
else update(x, y, c, rson);
}
}
int subQuery(int xrt, int yl, int yr, int l, int r, int rt) {
if(yl <= l && r <= yr) return s[xrt][rt];
else {
int m = l + r >> 1;
int res = -1;
if(yl <= m) res = subQuery(xrt, yl, yr, lson);
if(yr > m) res = max(res, subQuery(xrt, yl, yr, rson));
return res;
}
}
int query(int xl, int xr, int yl, int yr, int l, int r, int rt) {
if(xl <= l && r <= xr) return subQuery(rt, yl, yr, 0, n, 1);
else {
int m = l + r >> 1;
int res = -1;
if(xl <= m) res = query(xl, xr, yl, yr, lson);
if(xr > m) res = max(res, query(xl, xr, yl, yr, rson));
return res;
}
}
int main() {
int t;
while(scanf("%d", &t) && t) {
n = 1000;
build(100, 200, 1);
while(t--) {
char ch[2];
int a, b;
double c, d;
scanf("%s", ch);
if(ch[0] == 'I') {
scanf("%d%lf%lf", &a, &c, &d);
update(a, c * 10, d * 10, 100, 200, 1);
} else {
scanf("%d%d%lf%lf", &a, &b, &c, &d);
int cc = c * 10, dd = d * 10;
if(a > b) swap(a, b);
if(cc > dd) swap(cc, dd);
int ans = query(a, b, cc, dd, 100, 200, 1);
if(ans == -1) printf("-1\n");
else printf("%.1f\n", ans / 10.0);
}
}
}
return 0;
}
线段树合并
P4556 [Vani有约会]雨天的尾巴 /【模板】线段树合并
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 1e5 + 10;
struct {
int l, r, maxt,maxn;
}tree[N<<6];
struct query {
int x, y, z;
}q[N];
vector >e(N);
int top[N], siz[N], son[N], deep[N], fa[N],root[N],ans[N],maxn=0,cnt=0;
void dfs1(int x, int father) {
deep[x] = deep[father] + 1, siz[x] = 1, fa[x] = father;
for (int i : e[x]) {
if (i == father) continue;
dfs1(i, x);
siz[x] += siz[i];
if (siz[i] > siz[son[x]]) son[x] = i;
}
}
void dfs2(int x, int topx) {
top[x] = topx;
if (!son[x]) return;
dfs2(son[x], topx);
for (int i : e[x]) {
if (i == fa[x] || i == son[x]) continue;
dfs2(i, i);
}
}
int lca(int x, int y) {
while (top[x] != top[y]) {
if (deep[top[x]] > deep[top[y]]) x = fa[top[x]];
else y = fa[top[y]];
}
return deep[x] < deep[y] ? x : y;
}
void pushup(int x) {
if (tree[tree[x].l].maxt >= tree[tree[x].r].maxt) {
tree[x].maxt = tree[tree[x].l].maxt;
tree[x].maxn = tree[tree[x].l].maxn;
}
else {
tree[x].maxt = tree[tree[x].r].maxt;
tree[x].maxn = tree[tree[x].r].maxn;
}
}
void add(int& x, int l, int r, int pos, int k) {
if (!x) x = ++cnt;
if (l == r) {
tree[x].maxt += k;
tree[x].maxn = pos;
return;
}
int mid = (l + r) >> 1;
if (pos <= mid) add(tree[x].l, l, mid, pos, k);
else add(tree[x].r, mid + 1, r, pos, k);
pushup(x);
}
void merge(int& x, int y, int l, int r) {
if (!x || !y) { x = x + y; return; }
if (l == r) {
tree[x].maxt += tree[y].maxt;
tree[x].maxn = l;
return;
}
int mid = (l + r) >> 1;
merge(tree[x].l, tree[y].l, l, mid);
merge(tree[x].r, tree[y].r, mid+1, r);
pushup(x);
}
void dfs(int x, int father) {
for (int i : e[x]) {
if (i == father) continue;
dfs(i, x);
merge(root[x], root[i], 1, maxn);
}
if(tree[root[x]].maxt) ans[x] = tree[root[x]].maxn;
}
void solve() {
int n, m;
cin >> n >> m;
for (int i = 1; i < n; ++i) {
int u, v;
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs1(1, 0);
dfs2(1, 1);
for (int i = 1; i <= m; ++i) {
cin >> q[i].x >> q[i].y >> q[i].z;
maxn = max(maxn, q[i].z);
}
for (int i = 1; i <= m; ++i) {
int d = lca(q[i].x, q[i].y);
add(root[q[i].x], 1, maxn, q[i].z, 1);
add(root[q[i].y], 1, maxn, q[i].z, 1);
add(root[d], 1, maxn, q[i].z, -1);
add(root[fa[d]], 1, maxn, q[i].z, -1);
}
dfs(1, 0);
for (int i = 1; i <= n; ++i) cout << ans[i] << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
线段树分裂
P5494 【模板】线段树分裂
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e9;
const ll N = 2e5 + 10;
struct node {
int l, r;
ll val;
}tr[N << 5];
int root[N], tot = 0, cnt = 1;
void add(int& p, int l, int r, int k, int pos) {
if (!p) p = ++tot;
tr[p].val += k;
if (l == r) return;
int mid = (l + r) >> 1;
if (pos <= mid) add(tr[p].l, l, mid, k, pos);
else add(tr[p].r, mid + 1, r, k, pos);
}
ll query(int p, int l, int r, int ql, int qr) {
if (ql <= l && qr >= r) return tr[p].val;
ll ans = 0;
int mid = (l + r) >> 1;
if (ql <= mid) ans += query(tr[p].l, l, mid, ql, qr);
if (qr > mid) ans += query(tr[p].r, mid + 1, r, ql, qr);
return ans;
}
int kth(int p, int l, int r, ll k) {
if (l == r) return l;
int mid = (l + r) >> 1;
if (tr[tr[p].l].val >= k) return kth(tr[p].l, l, mid, k);
else return kth(tr[p].r, mid + 1, r, k - tr[tr[p].l].val);
}
void merge(int& x, int y) {
if (!x || !y) { x = x + y; return; }
tr[x].val += tr[y].val;
merge(tr[x].l, tr[y].l);
merge(tr[x].r, tr[y].r);
}
void split(int x, int& y, ll k) {
if (!x) return;
y = ++tot;
if (k > tr[tr[x].l].val) split(tr[x].r, tr[y].r, k - tr[tr[x].l].val);
else swap(tr[x].r, tr[y].r);
if (k < tr[tr[x].l].val) split(tr[x].l, tr[y].l, k);
tr[y].val = tr[x].val - k;
tr[x].val = k;
}
void solve() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
int k;
cin >> k;
add(root[1], 1, n, k, i);
}
for (int i = 1; i <= m; ++i) {
int op, p;
cin >> op >> p;
if (op == 0) {
int x, y;
cin >> x >> y;
ll k1 = query(root[p], 1, n, x, y), k2 = query(root[p], 1, n, 1, y);
int tmp = 0;
split(root[p], tmp, k2);
split(root[p], root[++cnt], k2 - k1);
merge(root[p], tmp);
}
else if (op == 1) {
int t;
cin >> t;
merge(root[p], root[t]);
}
else if (op == 2) {
int k, q;
cin >> k >> q;
add(root[p], 1, n, k, q);
}
else if (op == 3) {
int x, y;
cin >> x >> y;
cout << query(root[p], 1, n, x, y) << '\n';
}
else {
ll k;
cin >> k;
if (k > tr[root[p]].val) cout << -1 << '\n';
else cout << kth(root[p], 1, n, k) << '\n';
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
线段树分治
P5787 二分图 /【模板】线段树分治
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 4e5 + 10;
struct edge {
int u, v;
}e[N];
vector > t(N);
stack st;
int n, m, k, fa[N], cnt[N];
int find(int x) {
if (x == fa[x]) return x;
else return find(fa[x]);
}
void merge(int x, int y) {
x = find(x), y = find(y);
if (cnt[x] > cnt[y]) swap(x, y);
st.push({ x, cnt[x] == cnt[y] });
if (cnt[x] == cnt[y]) cnt[y]++;
fa[x] = y;
}
bool query(int x, int y) {
return find(x) == find(y);
}
void modify(int x, int l, int r, int ql, int qr, int id) {
if (ql <= l && qr >= r) {
t[x].push_back(id);
return;
}
int mid = l + r >> 1;
if (ql <= mid) modify(x << 1, l, mid, ql, qr, id);
if (qr > mid) modify(x << 1 | 1, mid + 1, r, ql, qr, id);
}
void query(int x, int l, int r) {
bool f = 1;
int last = st.size();
for (int i : t[x]) {
if (query(e[i].u, e[i].v)) {
for (int j = l; j <= r; ++j) cout << "No\n";
f = 0;
break;
}
merge(e[i].u, e[i].v + n);
merge(e[i].v, e[i].u + n);
}
if (f) {
if (l == r) cout << "Yes\n";
else {
int mid = l + r >> 1;
query(x << 1, l, mid);
query(x << 1 | 1, mid + 1, r);
}
}
while (st.size() > last) {
cnt[fa[st.top().first]] -= st.top().second;
fa[st.top().first] = st.top().first;
st.pop();
}
}
void solve() {
cin >> n >> m >> k;
for (int i = 1; i <= m; ++i) {
cin >> e[i].u >> e[i].v;
int l, r;
cin >> l >> r;
l++;
modify(1, 1, k, l, r, i);
}
for (int i = 1; i <= 2 * n; ++i) fa[i] = i;
query(1, 1, k);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
可持久化线段树
P3919 【模板】可持久化线段树 1(可持久化数组)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
#define P pair
const double eps = 1e-8;
const LL INF = 1e18;
const LL N = 1e6 + 10;
struct {
int l, r,val;
}tree[N << 5];
LL a[N], b[N], root[N], cnt = 0;
int build(int l, int r) {
int res = ++cnt;
if (l == r) {
tree[res].val = a[l];
return res;
}
int mid = (l + r) >> 1;
tree[res].l=build(l, mid);
tree[res].r=build(mid + 1, r);
return res;
}
int modify(int x, int l, int r, int index,LL k) {
int res = ++cnt;
if (l == r) {
tree[res].val = k;
return res;
}
tree[res].l = tree[x].l;
tree[res].r = tree[x].r;
int mid = (l + r) >> 1;
if (index <= mid) tree[res].l = modify(tree[x].l, l, mid, index,k);
else tree[res].r = modify(tree[x].r, mid + 1,r, index,k);
return res;
}
LL query(int x, int l, int r, int index) {
if (l == r) return tree[x].val;
int mid = (l + r) >> 1;
if (index<=mid) return query(tree[x].l, l, mid, index);
else return query(tree[x].r, mid + 1, r, index);
}
void solve() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i) cin >> a[i];
root[0]=build(1, n);
for (int i = 1; i <= m; ++i) {
int x, op, index;
cin >> x >> op >> index;
if (op == 1) {
LL k;
cin >> k;
root[i]=modify(root[x], 1, n, index, k);
}
else {
cout << query(root[x], 1, n, index) << '\n';
root[i] = root[x];
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
k大/小问题
P3834 【模板】可持久化线段树 2
建树
查询
空间
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
#define P pair
const double eps = 1e-8;
const LL INF = 1e18;
const LL N = 2e5 + 10;
struct {
int l, r, sum;
}tree[N<<5];
LL a[N], b[N],root[N],cnt=0;
int modify(int x, int l, int r, int k) {
int res = ++cnt;
tree[res].l = tree[x].l;
tree[res].r = tree[x].r;
tree[res].sum = tree[x].sum + 1;
int mid = (l + r) >> 1;
if (l != r) {
if (k <= mid) tree[res].l = modify(tree[x].l, l, mid, k);
else tree[res].r = modify(tree[x].r, mid + 1, r, k);
}
return res;
}
LL query(int u, int v, int l, int r, int k) {
if (l == r) return b[l];
int x = tree[tree[u].l].sum - tree[tree[v].l].sum;
int mid = (l + r) >> 1;
if (x >= k) return query(tree[u].l, tree[v].l, l, mid, k);
else return query(tree[u].r, tree[v].r, mid+1, r, k - x);
}
void solve() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
b[i] = a[i];
}
sort(b + 1, b + n + 1);
int size = unique(b + 1, b + n + 1) - b - 1;
for (int i = 1; i <= n; ++i) {
int k = lower_bound(b + 1, b + size + 1, a[i]) - b;
root[i] = modify(root[i - 1], 1, size, k);
}
for (int i = 1; i <= m; ++i) {
int l, r, k;
cin >> l >> r >> k;
cout << query(root[r], root[l - 1], 1, size, k)<<'\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
树的重心
poj3107 Godfather
参考博客
#include
#include
#include
#include
using namespace std;
#define N 50005
#define inf 0x3f3f3f3f
struct node{
int v,to;
} edge[N*2];
int cnt,x,y,n,sum,num,head[N],dp[N],ans[N];
void add(int u,int v){
edge[++cnt].to=head[u];
edge[cnt].v=v;
head[u]=cnt;
}
void dfs(int u,int pre){
dp[u]=1;
int temp=0;
for(int i=head[u]; i!=-1; i=edge[i].to){
int v=edge[i].v;
if(v==pre)continue;
dfs(v,u);
dp[u]+=dp[v];
temp=max(temp,dp[v]);
}
temp=max(temp,n-dp[u]);
if(temp
树的直径(dfs)
参考OI Wiki
不能用于带负权树
#include
using namespace std;
#define LL long long
const LL N = 1e4 + 10;
int n, c, d[N];
vector e(N);
void dfs(int u, int fa) {
for (int v : e[u]) {
if (v == fa) continue;
d[v] = d[u] + 1;
if (d[v] > d[c]) c = v;
dfs(v, u);
}
}
int main() {
cin >> n;
for (int i = 1; i < n; i++) {
int u, v;
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs(1, 0);
d[c] = 0, dfs(c, 0);
cout << d[c];
return 0;
}
树的直径(树形dp)
参考OI Wiki
无法得到完整路径
#include
using namespace std;
#define LL long long
const LL N = 1e4 + 10;
int n, d = 0, d1[N], d2[N];
vector e(N);
void dfs(int u, int fa) {
d1[u] = d2[u] = 0;
for (int v : e[u]) {
if (v == fa) continue;
dfs(v, u);
int t = d1[v] + 1;
if (t > d1[u])
d2[u] = d1[u], d1[u] = t;
else if (t > d2[u])
d2[u] = t;
}
d = max(d, d1[u] + d2[u]);
}
int main() {
cin >> n;
for (int i = 1; i < n; i++) {
int u, v;
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs(1, 0);
cout << d;
return 0;
}
LCA(倍增)
P3379 【模板】最近公共祖先(LCA)
在线
预处理
查询
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
#define P pair
const double eps = 1e-8;
const LL INF = 1e18;
const LL N = 5e5 + 10;
int n, m, s, deep[N], fa[N][20];
vector >e(N);
void dfs(int x, int father) {
deep[x] = deep[father] + 1;
fa[x][0] = father;
for (int i = 1; (1 << i) <= deep[x]; ++i) {
fa[x][i] = fa[fa[x][i - 1]][i - 1];
}
for (int i : e[x]) {
if (i == father) continue;
dfs(i, x);
}
}
int lca(int x, int y) {
if (deep[x] <= deep[y]) swap(x, y);
for (int i = 19; i >= 0; --i) {
if (deep[x] - (1 << i) >= deep[y]) x = fa[x][i];
}
if (x == y) return x;
for (int i = 19; i >= 0; --i) {
if (fa[x][i] != fa[y][i]) {
x = fa[x][i];
y = fa[y][i];
}
}
return fa[x][0];
}
void solve() {
cin >> n >> m >> s;
for (int i = 1; i < n; ++i) {
int u, v;
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs(s, 0);
for (int i = 1; i <= m; ++i) {
int x, y;
cin >> x >> y;
cout << lca(x, y) << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
LCA(tarjan)
P3379 【模板】最近公共祖先(LCA)
离线
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
#define P pair
const double eps = 1e-8;
const LL INF = 1e18;
const LL N = 5e5 + 10;
int n, m, s, ans[N], f[N], vis[N];
vector >e(N);
vector >q(N);
int find(int x) {
if (f[x] == x) return x;
return f[x] = find(f[x]);
}
void tarjan(int x) {
vis[x] = 1;
for (int i : e[x]) {
if (vis[i] == 0) {
tarjan(i);
f[i] = x;
}
}
for (P i : q[x]) {
int u = i.first;
if (vis[u]) ans[i.second] = find(u);
}
}
void solve() {
cin >> n >> m >> s;
for (int i = 1; i <= n; ++i) f[i] = i;
for (int i = 1; i < n; ++i) {
int u, v;
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
for (int i = 1; i <= m; ++i) {
int x, y;
cin >> x >> y;
q[x].push_back(P(y, i));
q[y].push_back(P(x, i));
}
tarjan(s);
for (int i = 1; i <= m; ++i) cout << ans[i] << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
LCA(重链剖分)
P3379 【模板】最近公共祖先(LCA)
在线
预处理
查询
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 5e5 + 10;
ll top[N], son[N], siz[N], fa[N], deep[N];
vector >e(N);
void dfs1(int x, int father) {
deep[x] = deep[father] + 1, siz[x] = 1, fa[x] = father;
for (int i : e[x]) {
if (i == father) continue;
dfs1(i, x);
siz[x] += siz[i];
if (siz[son[x]] < siz[i]) son[x] = i;
}
}
void dfs2(int x, int topx) {
top[x] = topx;
if (!son[x]) return;
dfs2(son[x], topx);
for (int i : e[x]) {
if (i == fa[x] || i == son[x]) continue;
dfs2(i, i);
}
}
int lca(int x, int y) {
while (top[x] != top[y]) {
if (deep[top[x]] >= deep[top[y]]) x = fa[top[x]];
else y = fa[top[y]];
}
return deep[x] < deep[y] ? x : y;
}
void solve() {
int n, m,s;
cin >> n >> m>>s;
for (int i = 1; i < n; ++i) {
int u, v;
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs1(s, 0);
dfs2(s, s);
for (int i = 1; i <= m; ++i) {
int x, y;
cin >> x >> y;
cout << lca(x, y) << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
树上差分
P3128 [USACO15DEC]Max Flow P
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
#define P pair
const double eps = 1e-8;
const LL INF = 1e18;
const LL N = 5e4 + 10;
int n, m,ans=0, deep[N], fa[N][20],d[N];
vector >e(N);
void dfs1(int x, int father) {
deep[x] = deep[father] + 1;
fa[x][0] = father;
for (int i = 1; (1 << i) <= deep[x]; ++i) {
fa[x][i] = fa[fa[x][i - 1]][i - 1];
}
for (int i : e[x]) {
if (i == father) continue;
dfs1(i, x);
}
}
int lca(int x, int y) {
if (deep[x] <= deep[y]) swap(x, y);
for (int i = 19; i >= 0; --i) {
if (deep[x] - (1 << i) >= deep[y]) x = fa[x][i];
}
if (x == y) return x;
for (int i = 19; i >= 0; --i) {
if (fa[x][i] != fa[y][i]) {
x = fa[x][i];
y = fa[y][i];
}
}
return fa[x][0];
}
void dfs2(int x,int father) {
for (int i : e[x]) {
if (i == father) continue;
dfs2(i, x);
d[x] += d[i];
}
ans = max(ans, d[x]);
}
void solve() {
cin >> n >> m;
for (int i = 1; i < n; ++i) {
int u, v;
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs1(1, 0);
for (int i = 1; i <= m; ++i) {
int x, y;
cin >> x >> y;
int u=lca(x, y);
d[x]++;
d[y]++;
d[u]--;
d[fa[u][0]]--;
}
dfs2(1,0);
cout << ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
基础莫队
P1972 [SDOI2009] HH的项链
该题卡莫队,快读快写48pts,主要看思想
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
#define P pair
const double eps = 1e-8;
const LL INF = 1e18;
const LL MAXN = 1e6 + 10;
int a[MAXN], block, belong[MAXN], ans[MAXN], cnt[MAXN], Ans = 0;
char buf[10];
struct query {
int l, r, id;
bool operator < (const query a)const {
return belong[l] == belong[a.l] ? belong[l] % 2 ? ra.r : belong[l] < belong[a.l];
}
}q[MAXN];
inline int read() {
int res = 0;
char ch = getchar();
while (ch < '0' || ch>'9') ch = getchar();
while (ch >= '0' && ch <= '9') { res = (res << 3) + (res << 1) + (ch ^ 48); ch = getchar(); }
return res;
}
inline void write(int x) {
int pos = 0;
while (x) {
buf[++pos] = x % 10 + '0';
x /= 10;
}
while (pos--) putchar(buf[pos+1]);
putchar('\n');
}
inline void Add(int pos) {
cnt[a[pos]]++;
if (cnt[a[pos]] == 1) Ans++;
}
inline void Delete(int pos) {
cnt[a[pos]]--;
if (cnt[a[pos]] == 0) Ans--;
}
inline void solve() {
int n, m;
n = read();
block = sqrt(n);
for (int i = 1; i <= n; ++i) {
a[i] = read();
belong[i] = (i - 1) / block + 1;
}
m = read();
for (int i = 1; i <= m; ++i) {
int l, r;
q[i].l = read(), q[i].r = read();
q[i].id = i;
}
sort(q + 1, q + m + 1);
int L = 1, R = 0;
for (int i = 1; i <= m; ++i) {
while (L < q[i].l) Delete(L++);
while (R > q[i].r) Delete(R--);
while (L > q[i].l) Add(--L);
while (R < q[i].r) Add(++R);
ans[q[i].id] = Ans;
}
for (int i = 1; i <= m; ++i) write(ans[i]);
}
int main() {
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
带修莫队
P1903 [国家集训队] 数颜色 / 维护队列
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 1e6 + 10;
int a[N], block, belong[N], ans[N], cnt[N], Ans = 0;
struct {
int p, c;
}p[N];
struct query{
int l, r, t, id;
bool operator<(const query a) {
return belong[l] == belong[a.l] ? belong[r] == belong[a.r] ? t < a.t : belong[r] < belong[a.r] : belong[l] < belong[a.l];
}
}q[N];
void del(int x) {
cnt[x]--;
if (cnt[x] == 0) Ans--;
}
void add(int x) {
cnt[x]++;
if (cnt[x] == 1) Ans++;
}
void modify(int x,int t) {
if (p[t].p >= q[x].l && p[t].p <= q[x].r) {
del(a[p[t].p]);
add(p[t].c);
}
swap(a[p[t].p], p[t].c);
}
void solve() {
int n, m;
cin >> n >> m;
block = pow(n, 0.666666);
for (int i = 1; i <= n; ++i) {
cin >> a[i];
belong[i] = (i - 1) / block + 1;
}
int cnt1 = 0, cnt2 = 0;
for (int i = 1; i <= m; ++i) {
char ch;
cin >> ch;
if (ch == 'Q') {
cin >> q[++cnt1].l >> q[cnt1].r;
q[cnt1].t = cnt2, q[cnt1].id = cnt1;
}
else {
cin >> p[++cnt2].p >> p[cnt2].c;
}
}
int L = 1, R = 0, cur = 0;
sort(q + 1, q + cnt1 + 1);
for (int i = 1; i <= cnt1; ++i) {
while (L < q[i].l) del(a[L++]);
while (R > q[i].r) del(a[R--]);
while (L > q[i].l) add(a[--L]);
while (R < q[i].r) add(a[++R]);
while (cur < q[i].t) modify(i,++cur);
while (cur > q[i].t) modify(i,cur--);
ans[q[i].id] = Ans;
}
for (int i = 1; i <= cnt1; ++i) cout << ans[i] << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
树上莫队
COT2 - Count on a tree II
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 1e5 + 10;
ll a[N], b[N], vis[N], belong[N],cnt[N], st[N], ed[N], pos[N], top[N], son[N], siz[N], fa[N], deep[N], ans[N], block, Ans = 0, tot = 0;
struct query {
int l, r, lca,id;
bool operator<(const query a) const {
return belong[l] == belong[a.l] ? r < a.r : belong[l] < belong[a.l];
}
}q[N];
vector >e(N);
void dfs1(int x,int father) {
deep[x] = deep[father] + 1, siz[x] = 1, fa[x] = father, st[x] = ++tot, pos[tot] = x;
for (int i : e[x]) {
if (i == father) continue;
dfs1(i,x);
siz[x] += siz[i];
if (siz[son[x]] < siz[i]) son[x] = i;
}
ed[x] = ++tot, pos[tot] = x;
}
void dfs2(int x, int topx) {
top[x] = topx;
if (!son[x]) return;
dfs2(son[x], topx);
for (int i : e[x]) {
if (i == fa[x] || i == son[x]) continue;
dfs2(i, i);
}
}
int lca(int x, int y) {
while (top[x] != top[y]) {
if (deep[top[x]] >= deep[top[y]]) x = fa[top[x]];
else y = fa[top[y]];
}
return deep[x] < deep[y] ? x : y;
}
void modify(int x) {
if (vis[x]) {
cnt[a[x]]--;
if (cnt[a[x]] == 0) Ans--;
}
else {
cnt[a[x]]++;
if (cnt[a[x]] == 1) Ans++;
}
vis[x] ^= 1;
}
void solve() {
int n, m;
cin >> n >> m;
block = sqrt(n);
for (int i = 1; i <= n; ++i) {
cin >> a[i];
b[i] = a[i];
}
for (int i = 1; i <= 2 * n; ++i) belong[i] = (i - 1) / block + 1;
sort(b + 1, b + n + 1);
int len = unique(b + 1, b + n + 1) - b-1;
for (int i = 1; i <= n; ++i) a[i] = lower_bound(b + 1, b + len + 1, a[i]) - b;
for (int i = 1; i < n; ++i) {
int u, v;
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs1(1,0);
dfs2(1,1);
for (int i = 1; i <= m; ++i) {
int x, y;
cin >> x >> y;
if (st[x] > st[y]) swap(x, y);
int d = lca(x, y);
if (d == x) q[i].l = st[x], q[i].r = st[y];
else q[i].l = ed[x], q[i].r = st[y], q[i].lca = d;
q[i].id = i;
}
sort(q + 1, q + m + 1);
int L = 1, R = 0;
for (int i = 1; i <= m; ++i) {
while (L < q[i].l) modify(pos[L++]);
while (R > q[i].r) modify(pos[R--]);
while (L > q[i].l) modify(pos[--L]);
while (R < q[i].r) modify(pos[++R]);
if (q[i].lca) modify(q[i].lca);
ans[q[i].id] = Ans;
if (q[i].lca) modify(q[i].lca);
}
for (int i = 1; i <= m; ++i) cout << ans[i] << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
回滚莫队
P5906 【模板】回滚莫队&不删除莫队
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 2e5 + 10;
int a[N], b[N], belong[N], st[N], ed[N], ed2[N], ans[N], block;
struct query {
int l, r, id;
bool operator<(const query a)const {
return belong[l] == belong[a.l] ? r < a.r : belong[l] < belong[a.l];
}
}q[N];
void solve() {
int n, m;
cin >> n;
block = sqrt(n);
for (int i = 1; i <= n; ++i) {
cin >> a[i];
b[i] = a[i];
belong[i] = (i - 1) / block + 1;
}
sort(b + 1, b + n + 1);
int len = unique(b + 1, b + n + 1) - b - 1;
for (int i = 1; i <= n; ++i) a[i] = lower_bound(b + 1, b + len + 1, a[i]) - b;
cin >> m;
for (int i = 1; i <= m; ++i) {
cin >> q[i].l >> q[i].r;
q[i].id = i;
}
sort(q + 1, q + m + 1);
int last = 0, L=1, R=0,Ans1,Ans2;
for (int i = 1; i <= m; ++i) {
if (belong[q[i].l] == belong[q[i].r]) {
Ans1 = 0;
for (int j = q[i].l; j <= q[i].r; ++j) st[a[j]] = 0;
for (int j = q[i].l; j <= q[i].r; ++j) {
if (!st[a[j]]) st[a[j]] = j;
Ans1 = max(Ans1, j - st[a[j]]);
}
for (int j = q[i].l; j <= q[i].r; ++j) st[a[j]] = 0;
ans[q[i].id] = Ans1;
}
else {
if (belong[q[i].l] != last) {
Ans1 = 0;
for (int j = L; j <= R; ++j) st[a[j]] = ed[a[j]] = 0;
L = belong[q[i].l] * block;
R = L - 1;
last = belong[q[i].l];
}
while (R < q[i].r) {
R++;
if (!st[a[R]]) st[a[R]] = R;
ed[a[R]] = R;
Ans1 = max(Ans1, R - st[a[R]]);
}
int p = L;
Ans2 = 0;
while (q[i].l < p) {
p--;
if (!ed2[a[p]]) ed2[a[p]] = p;
Ans2 = max(Ans2, max(ed[a[p]], ed2[a[p]]) - p);
}
for (int j = p; j < L; ++j) ed2[a[j]] = 0;
ans[q[i].id] = max(Ans1,Ans2);
}
}
for (int i = 1; i <= m; ++i) cout << ans[i] << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
二次离线莫队
P4887 【模板】莫队二次离线(第十四分块(前体))
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 1e5 + 10;
int a[N], belong[N], cnt[N], pre[N], block;
ll ans[N];
struct query {
int l, r, id;
ll ans;
bool operator<(const query a)const {
return belong[l] == belong[a.l] ? r < a.r : belong[l] < belong[a.l];
}
}q[N];
vector v;
vector > >p(N);
int bitcount(int x) {
int res = 0;
while (x) {
if (x & 1) res++;
x >>= 1;
}
return res;
}
void solve() {
int n, m, k;
cin >> n >> m >> k;
if (k > 14) {
for (int i = 1; i <= m; ++i) cout << 0 << '\n';
return;
}
block = sqrt(n);
for (int i = 1; i <= n; ++i) {
cin >> a[i];
belong[i] = (i - 1) / block + 1;
}
for (int i = 0; i < 16384; ++i) {
if (bitcount(i) == k) v.push_back(i);
}
for (int i = 1; i <= n; ++i) {
for (int j : v) cnt[a[i] ^ j]++;
pre[i] = cnt[a[i + 1]];
}
memset(cnt, 0, sizeof(cnt));
for (int i = 1; i <= m; ++i) {
cin >> q[i].l >> q[i].r;
q[i].id = i;
}
sort(q + 1, q + m + 1);
int L = 1, R = 0;
for (int i = 1; i <= m; ++i) {
ll Ans = 0;
if (L < q[i].l) p[R].push_back({ L, q[i].l - 1, -i });
while (L < q[i].l) {
Ans += pre[L - 1];
L++;
}
if (L > q[i].l) p[R].push_back({ q[i].l, L - 1, i });
while (L > q[i].l) {
L--;
Ans -= pre[L - 1];
}
if (R < q[i].r) p[L - 1].push_back({ R + 1, q[i].r, -i });
while (R < q[i].r) {
R++;
Ans += pre[R - 1];
}
if (R > q[i].r) p[L - 1].push_back({ q[i].r + 1,R,i });
while (R > q[i].r) {
Ans -= pre[R - 1];
R--;
}
q[i].ans = Ans;
}
for (int i = 1; i <= n; ++i) {
for (int j : v) cnt[a[i] ^ j]++;
for (auto t : p[i]) {
int l, r, id;
tie(l, r, id) = t;
for (int j = l; j <= r; ++j) {
int temp = cnt[a[j]];
if (j <= i && k == 0) temp--;
if (id < 0) q[-id].ans -= temp;
else q[id].ans += temp;
}
}
}
for (int i = 1; i <= m; ++i) q[i].ans += q[i - 1].ans;
for (int i = 1; i <= m; ++i) ans[q[i].id] = q[i].ans;
for (int i = 1; i <= m; ++i) cout << ans[i] << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
块状链表
P4008 [NOI2003] 文本编辑器
参考《算法竞赛》
#include
#include
#include
#include
using namespace std;
#define it list >::iterator
int block = 2500;
list > List;
it Next(it x) {
return ++x;
}
it Find(int& x) {
for (it i = List.begin(); ; ++i) {
if (i==List.end()||x <= i->size()) return i;
x -= i->size();
}
}
void Output(int l, int r) {
it L = Find(l), R = Find(r);
if (L == R) {
for (int i = l; i < r; ++i) {
cout << L->at(i);
}
}
else {
for (int i = l; i < L->size(); ++i) cout << L->at(i);
for (++L; L != R; ++L) {
for (int i = 0; i < L->size(); ++i) cout << L->at(i);
}
for (int i = 0; i < r; ++i) cout << R->at(i);
}
cout << '\n';
}
void Merge(it x) {
x->insert(x->end(), Next(x)->begin(), Next(x)->end());
List.erase(Next(x));
}
void Split(it x, int pos) {
if (pos == x->size()) return;
List.insert(Next(x), vector(x->begin() + pos, x->end()));
x->erase(x->begin() + pos, x->end());
}
void Update() {
for (it i = List.begin(); i != List.end(); ++i) {
while (i->size() >= (block << 1)) Split(i, i->size() - block);
while (Next(i) != List.end() && i->size() + Next(i)->size() <= block) Merge(i);
while (Next(i) != List.end() && Next(i)->empty()) List.erase(Next(i));
}
}
void Insert(int pos, const vector& ch) {
it cur = Find(pos);
if (!List.empty()) {
Split(cur, pos);
List.insert(Next(cur), ch);
}
else List.insert(cur, ch);
Update();
}
void Delete(int l, int r) {
it L, R;
L = Find(l), Split(L, l);
R = Find(r), Split(R, r);
R++;
while (Next(L) != R) List.erase(Next(L));
Update();
}
int main() {
int n, len, pos=0;
vector ch;
cin >> n;
while (n--) {
string op;
cin >> op;
switch (op[0]) {
case 'M':
cin >> pos;
break;
case 'I':
cin >> len;
ch.clear(), ch.resize(len);
for (int i = 0; i < len; ++i) {
ch[i] = getchar();
while (ch[i] < 32 || ch[i] >126) ch[i] = getchar();
}
Insert(pos, ch);
break;
case 'D':
cin >> len;
Delete(pos, pos + len);
break;
case 'G':
cin >> len;
Output(pos, pos + len);
break;
case 'P':
--pos;
break;
case 'N':
++pos;
break;
}
}
return 0;
}
点分治
P3806 【模板】点分治1
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
#define P pair
const double eps = 1e-8;
const LL INF = 1e18;
const LL MAXN = 1e4 + 10;
const LL MAXM = 1e2 + 10;
struct edge {
int u, v, w;
edge(int u,int v,int w):u(u),v(v),w(w){}
};
vector >e(MAXN);
int n, m,root,minroot,cnt,q[MAXM],ans[MAXM],siz[MAXN],vis[MAXN],dis[MAXN],belong[MAXN],a[MAXN];
bool cmp(int a, int b) {
return dis[a] < dis[b];
}
void getroot(int x,int fa,int sum) {
siz[x] = 1;
int num = 0;
for (edge i : e[x]) {
if (i.v == fa||vis[i.v]) continue;
getroot(i.v, x,sum);
siz[x] += siz[i.v];
num = max(num, siz[i.v]);
}
num = max(num, sum - siz[x]);
if (num < minroot) {
minroot = num;
root = x;
}
}
void getdis(int x, int fa,int b) {
a[++cnt] = x;
belong[x] = b;
for (edge i : e[x]) {
if (i.v == fa || vis[i.v]) continue;
dis[i.v] = dis[x] + i.w;
getdis(i.v, x,b);
}
}
void calc(int x) {
cnt = 0;
a[++cnt] = x;
dis[x] = 0;
belong[x] = x;
for (edge i : e[x]) {
if (vis[i.v]) continue;
dis[i.v] = i.w;
getdis(i.v, x, i.v);
}
sort(a + 1, a + cnt + 1, cmp);
for (int i = 1; i <= m; ++i) {
if (ans[i]) continue;
int L = 1, R = cnt;
while (L < R) {
if (dis[a[L]] + dis[a[R]] < q[i]) L++;
else if (dis[a[L]] + dis[a[R]] > q[i]) R--;
else if (belong[a[L]] == belong[a[R]]) {
if (dis[a[R]] == dis[a[R - 1]]) R--;
else L++;
}
else {
ans[i] = 1;
break;
}
}
}
}
void divide(int x) {
vis[x] = 1;
calc(x);
for (edge i : e[root]) {
if (vis[i.v]) continue;
minroot = 0x3f3f3f3f;
getroot(i.v, x, siz[i.v]);
divide(root);
}
}
void solve() {
cin >> n >> m;
for (int i = 1; i < n; ++i) {
int u, v, w;
cin >> u >> v >> w;
e[u].push_back(edge(u, v, w));
e[v].push_back(edge(v, u, w));
}
for (int i = 1; i <= m; ++i) {
cin >> q[i];
}
minroot = 0x3f3f3f3f;
getroot(1,0,n);
divide(root);
for (int i = 1; i <= m; ++i) {
if (ans[i]) cout << "AYE\n";
else cout << "NAY\n";
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
边分治
待填
点分树
P6329 【模板】点分树 | 震波
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
#define P pair
const double eps = 1e-8;
const LL INF = 1e9;
const LL N = 1e5 + 10;
vector < vector >e(N);
int n, m, ans, rt, sum, minn;
int val[N], siz[N], fa[N], deep[N], f[N][20];
bool vis[N];
vectorC[2][N];
void dfs0(int x, int fa) {
f[x][0] = fa;
deep[x] = deep[fa] + 1;
for (int i = 1; (1 << i) <= deep[x]; ++i) f[x][i] = f[f[x][i - 1]][i - 1];
for (int i : e[x]) {
if (i == fa) continue;
dfs0(i, x);
}
}
int lca(int x, int y) {
if (deep[x] < deep[y]) swap(x, y);
for (int i = 19; i >= 0; --i) if (deep[f[x][i]] >= deep[y]) x = f[x][i];
if (x == y) return x;
for (int i = 19; i >= 0; --i) {
if (f[x][i] != f[y][i]) {
x = f[x][i];
y = f[y][i];
}
}
return f[x][0];
}
int getdis(int x, int y) {
return deep[x] + deep[y] - 2 * deep[lca(x, y)];
}
int lowbit(int x) {
return x & -x;
}
void add(int u, int opt, int x, int k) {
x++;
for (; x <= siz[u]; x += lowbit(x)) C[opt][u][x] += k;
}
int query(int u, int opt, int x) {
x++;
int res = 0;
x = min(x, siz[u]);
for (; x; x -= lowbit(x)) res += C[opt][u][x];
return res;
}
void findrt(int x, int fa) {
siz[x] = 1;
int res = 0;
for (int i : e[x]) {
if (i != fa && !vis[i]) {
findrt(i, x);
siz[x] += siz[i], res = max(res, siz[i]);
}
}
res = max(res, sum - siz[x]);
if (res < minn) minn = res, rt = x;
}
void dfs(int x) {
vis[x] = 1;
siz[x] = sum + 1;
C[0][x].resize(siz[x] + 1);
C[1][x].resize(siz[x] + 1);
for (int i : e[x]) {
if (!vis[i]) {
sum = siz[i], rt = 0, minn = INF;
findrt(i, 0);
fa[rt] = x;
dfs(rt);
}
}
}
void modify(int x, int k) {
for (int i = x; i; i = fa[i]) add(i, 0, getdis(x, i), k);
for (int i = x; fa[i]; i = fa[i]) add(i, 1, getdis(x, fa[i]), k);
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; ++i) cin >> val[i];
for (int i = 1; i < n; ++i) {
int u, v;
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs0(1, 0);
sum = n, minn = INF;
findrt(1, 0);
dfs(rt);
for (int i = 1; i <= n; ++i) modify(i, val[i]);
for (int i = 1; i <= m; ++i) {
int op, x, y;
cin >> op >> x >> y;
x ^= ans, y ^= ans;
if (op == 0) {
ans = 0;
ans += query(x, 0, y);
for (int i = x; fa[i]; i = fa[i]) {
int dis = getdis(x, fa[i]);
if (y >= dis) ans += query(fa[i], 0, y - dis) - query(i, 1, y - dis);
}
cout << ans << '\n';
}
else modify(x, y - val[x]), val[x] = y;
}
return 0;
}
重链剖分
P3384 【模板】重链剖分/树链剖分
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
#define P pair
const double eps = 1e-8;
const LL INF = 1e18;
const LL N = 1e5 + 10;
vector >e(N);
int n, m, root, p;
int val[N], nval[N], top[N], tag[N << 2], sum[N << 2], sze[N << 2], f[N], siz[N], deep[N], son[N], id[N], cnt = 0;
void dfs1(int x, int fa) {
deep[x] = deep[fa] + 1;
siz[x] = 1;
f[x] = fa;
for (int i : e[x]) {
if (i == fa) continue;
dfs1(i, x);
siz[x] += siz[i];
if (siz[son[x]] < siz[i]) son[x] = i;
}
}
void dfs2(int x, int topx) {
id[x] = ++cnt;
nval[cnt] = val[x];
top[x] = topx;
if (!son[x]) return;
dfs2(son[x], topx);
for (int i : e[x]) {
if (i == son[x] || i == f[x]) continue;
dfs2(i, i);
}
}
void pushup(int x) {
sum[x] = (sum[x << 1] + sum[x << 1 | 1]) % p;
}
void pushtag(int x, int k) {
sum[x] = (sum[x] + k * sze[x]) % p;
tag[x] = (tag[x] + k) % p;
}
void pushdown(int x) {
if (tag[x]) {
pushtag(x << 1, tag[x]);
pushtag(x << 1 | 1, tag[x]);
tag[x] = 0;
}
}
void build(int x, int l, int r) {
if (l == r) {
sum[x] = nval[l] % p;
sze[x] = 1;
return;
}
int mid = (l + r) >> 1;
build(x << 1, l, mid);
build(x << 1 | 1, mid + 1, r);
sze[x] = sze[x << 1] + sze[x << 1 | 1];
pushup(x);
}
void treemodify(int x, int l, int r, int ql, int qr, int k) {
if (ql <= l && qr >= r) {
pushtag(x, k);
return;
}
pushdown(x);
int mid = (l + r) >> 1;
if (ql <= mid) treemodify(x << 1, l, mid, ql, qr, k);
if (qr > mid) treemodify(x << 1 | 1, mid + 1, r, ql, qr, k);
pushup(x);
}
LL treequery(int x, int l, int r, int ql, int qr) {
if (ql <= l && qr >= r) return sum[x] % p;
LL res = 0;
pushdown(x);
int mid = (l + r) >> 1;
if (ql <= mid) res = (res + treequery(x << 1, l, mid, ql, qr)) % p;
if (qr > mid) res = (res + treequery(x << 1 | 1, mid + 1, r, ql, qr)) % p;
return res;
}
void modify(int x, int y, int k) {
while (top[x] != top[y]) {
if (deep[top[x]] < deep[top[y]]) swap(x, y);
treemodify(1, 1, n, id[top[x]], id[x], k);
x = f[top[x]];
}
if (deep[x] > deep[y]) swap(x, y);
treemodify(1, 1, n, id[x], id[y], k);
}
LL query(int x, int y) {
LL res = 0;
while (top[x] != top[y]) {
if (deep[top[x]] < deep[top[y]]) swap(x, y);
res = (res + treequery(1, 1, n, id[top[x]], id[x])) % p;
x = f[top[x]];
}
if (deep[x] > deep[y]) swap(x, y);
res = (res + treequery(1, 1, n, id[x], id[y])) % p;
return res;
}
void solve() {
cin >> n >> m >> root >> p;
for (int i = 1; i <= n; ++i) cin >> val[i];
for (int i = 1; i < n; ++i) {
int u, v;
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs1(root, 0);
dfs2(root, root);
build(1, 1, n);
for (int i = 1; i <= m; ++i) {
int op;
cin >> op;
if (op == 1) {
int x, y, k;
cin >> x >> y >> k;
modify(x, y, k);
}
else if (op == 2) {
int x, y;
cin >> x >> y;
cout << query(x, y) << '\n';
}
else if (op == 3) {
int x, k;
cin >> x >> k;
treemodify(1, 1, n, id[x], id[x] + siz[x] - 1, k);
}
else {
int x;
cin >> x;
cout << treequery(1, 1, n, id[x], id[x] + siz[x] - 1) << '\n';
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
长链剖分
P5903 【模板】树上 k 级祖先
预处理
查询
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 5e5 + 10;
#define ui unsigned int
ui s;
inline ui get(ui x) {
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
return s = x;
}
int deep[N], son[N], top[N], f[N][20], siz[N], bin[N];
vector > e(N), up(N), down(N);
void dfs1(int x) {
deep[x] = deep[f[x][0]] + 1, siz[x] = 1;
for (int i = 1; (1 << i) <= deep[x]; ++i) f[x][i] = f[f[x][i - 1]][i - 1];
for (int i : e[x]) {
dfs1(i);
siz[x] = max(siz[x], siz[i] + 1);
if (siz[i] > siz[son[x]]) son[x] = i;
}
}
void dfs2(int x, int topx) {
top[x] = topx;
down[topx].push_back(x);
if (!son[x]) return;
dfs2(son[x], topx);
for (int i : e[x]) {
if (i == son[x]) continue;
int temp = i;
up[i].push_back(i);
for (int j = 1; j <= siz[i]; ++j) {
up[i].push_back(f[temp][0]);
temp = f[temp][0];
}
dfs2(i, i);
}
}
void solve() {
int n, q, root;
cin >> n >> q >> s;
for (int i = 1; i <= n; ++i) {
cin >> f[i][0];
if (!f[i][0]) root = i;
else e[f[i][0]].push_back(i);
bin[i] = log2(i);
}
dfs1(root);
dfs2(root, root);
int temp = root;
up[root].push_back(root);
for (int i = 1; i <= siz[root]; ++i) {
up[root].push_back(f[temp][0]);
temp = f[temp][0];
}
ll last = 0, ans = 0;
for (int i = 1; i <= q; ++i) {
int x = (get(s) ^ last) % n + 1, k = (get(s) ^ last) % deep[x];
if (k == 0) {
last = x;
ans ^= (1ll * i * x);
continue;
}
int goal = deep[x] - k;
x = top[f[x][bin[k]]];
if (deep[x] < goal) x = down[x][goal - deep[x]];
else x = up[x][deep[x] - goal];
last = x;
ans ^= (1ll * i * x);
}
cout << ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
启发式合并
P3201 [HNOI2009] 梦幻布丁
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 1e6 + 10;
int a[N],mp[N],ans=0;
vector >e(N);
void merge(int& x, int& y) {
if (x == y) return;
if (e[x].size() > e[y].size()) swap(x, y);
for (int i : e[x]) {
if (a[i - 1] == y) ans--;
if (a[i + 1] == y) ans--;
}
for (int i : e[x]) a[i] = y;
e[y].insert(e[y].end(), e[x].begin(), e[x].end());
e[x].clear();
}
void solve() {
int n, m;
cin >> n >> m;
for (int i = 1; i <=n; ++i) {
cin >> a[i], mp[a[i]] = a[i];
e[a[i]].push_back(i);
}
for (int i = 1; i <= n; ++i) {
if (a[i - 1] != a[i]) ans++;
}
for (int i = 1; i <= m; ++i) {
int op;
cin >> op;
if (op == 1) {
int x, y;
cin >> x >> y;
merge(mp[x], mp[y]);
}
else cout << ans << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin >> _t;
while (_t--) {
solve();
}
return 0;
}
树上启发式合并
CF600E Lomsat gelral
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 1e5 + 10;
int son[N], siz[N], color[N], cnt[N];
ll ans[N], maxn = 0, sum = 0;
vector >e(N);
void dfs1(int x, int father) {
siz[x] = 1;
for (int i : e[x]) {
if (i == father) continue;
dfs1(i, x);
siz[x] += siz[i];
if (siz[i] > siz[son[x]]) son[x] = i;
}
}
void modify(int x, int father, int k, int pson) {
int c = color[x];
cnt[c] += k;
if (cnt[c] > maxn) {
maxn = cnt[c];
sum = c;
}
else if (cnt[c] == maxn) sum += c;
for (int i : e[x]) {
if (i == father || i == pson) continue;
modify(i, x, k, pson);
}
}
void dfs2(int x, int father, int op) {
for (int i : e[x]) {
if (i == father || i == son[x]) continue;
dfs2(i, x, 0);
}
if (son[x]) dfs2(son[x], x, 1);
modify(x, father, 1, son[x]);
ans[x] = sum;
if (op == 0) {
modify(x, father, -1, 0);
maxn = sum = 0;
}
}
void solve() {
int n;
cin >> n;
for (int i = 1; i <= n; ++i) cin >> color[i];
for (int i = 1; i < n; ++i) {
int u, v;
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs1(1, 0);
dfs2(1, 0, 1);
for (int i = 1; i <= n; ++i) cout << ans[i] << " ";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin >> _t;
while (_t--) {
solve();
}
return 0;
}
替罪羊树
P3369 【模板】普通平衡树
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 1e5 + 10;
const double alpha = 0.7;
struct node {
int l, r, key, siz, tot, del;
}tr[N];
int st[N], order[N];
int root = 0, cnt, tot = 0;
void initnode(int x) {
tr[x].l = tr[x].r = 0;
tr[x].siz = tr[x].tot = tr[x].del = 1;
}
void pushup(int x) {
tr[x].siz = tr[tr[x].l].siz + tr[tr[x].r].siz + 1;
tr[x].tot = tr[tr[x].l].tot + tr[tr[x].r].tot + 1;
}
bool notbalance(int x) {
if ((double)tr[x].siz * alpha <= (double)max(tr[tr[x].l].siz, tr[tr[x].r].siz)) return 1;
else return 0;
}
void inorder(int x) {
if (!x) return;
inorder(tr[x].l);
if (tr[x].del) order[++cnt] = x;
else st[++tot] = x;
inorder(tr[x].r);
}
void build(int& x, int l, int r) {
int mid = (l + r) >> 1;
x = order[mid];
if (l == r) {
initnode(x);
return;
}
if (l < mid) build(tr[x].l, l, mid - 1);
if (l == mid) tr[x].l = 0;
build(tr[x].r, mid + 1, r);
pushup(x);
}
void rebuild(int& x) {
cnt = 0;
inorder(x);
if (cnt) build(x, 1, cnt);
else x = 0;
}
int rnk(int x, int k) {
if (!x) return 0;
if (k > tr[x].key) return tr[tr[x].l].siz + tr[x].del + rnk(tr[x].r, k);
else return rnk(tr[x].l, k);
}
int kth(int k) {
int x = root;
while (x) {
if (tr[x].del && tr[tr[x].l].siz + 1 == k) return tr[x].key;
else if (tr[tr[x].l].siz >= k) x = tr[x].l;
else {
k -= tr[tr[x].l].siz + tr[x].del;
x = tr[x].r;
}
}
return tr[x].key;
}
void insert(int& x, int k) {
if (!x) {
x = st[tot--];
tr[x].key = k;
initnode(x);
return;
}
tr[x].siz++;
tr[x].tot++;
if (tr[x].key >= k) insert(tr[x].l, k);
else insert(tr[x].r, k);
if (notbalance(x)) rebuild(x);
}
void removek(int& x, int k) {
tr[x].siz--;
if (tr[x].del && tr[tr[x].l].siz + 1 == k) {
tr[x].del = 0;
return;
}
if (tr[tr[x].l].siz + tr[x].del >= k) removek(tr[x].l, k);
else removek(tr[x].r, k - tr[tr[x].l].siz - tr[x].del);
}
void remove(int k) {
removek(root, rnk(root, k) + 1);
if (tr[root].tot * alpha >= tr[root].siz) rebuild(root);
}
void solve() {
for (int i = N - 1; i >= 1; --i) st[++tot] = i;
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
int op, x;
cin >> op >> x;
if (op == 1) insert(root, x);
else if (op == 2) remove(x);
else if (op == 3) cout << rnk(root, x) + 1 << '\n';
else if (op == 4) cout << kth(x) << '\n';
else if (op == 5) cout << kth(rnk(root, x)) << '\n';
else cout << kth(rnk(root, x + 1) + 1) << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
Treap
P3369 【模板】普通平衡树
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e9;
const ll N = 1e5 + 10;
struct node {
int l, r, key, val, cnt, siz;
}tr[N];
int root, tot = 0;
int creatnode(int k) {
tr[++tot].key = k;
tr[tot].val = rand();
tr[tot].cnt = tr[tot].siz = 1;
return tot;
}
void pushup(int x) {
tr[x].siz = tr[tr[x].l].siz + tr[tr[x].r].siz + tr[x].cnt;
}
void build() {
creatnode(-INF), creatnode(INF);
root = 1;
tr[1].r = 2;
pushup(root);
}
void zig(int& x) {
int p = tr[x].l;
tr[x].l = tr[p].r, tr[p].r = x, x = p;
pushup(tr[x].r), pushup(x);
}
void zag(int& x) {
int p = tr[x].r;
tr[x].r = tr[p].l, tr[p].l = x, x = p;
pushup(tr[x].l), pushup(x);
}
void insert(int& x, int k) {
if (!x) x = creatnode(k);
else if (k == tr[x].key) tr[x].cnt++;
else if (k < tr[x].key) {
insert(tr[x].l, k);
if (tr[tr[x].l].val > tr[x].val) zig(x);
}
else {
insert(tr[x].r, k);
if (tr[tr[x].r].val > tr[x].val) zag(x);
}
pushup(x);
}
void remove(int& x, int k) {
if (!x) return;
if (k == tr[x].key) {
if (tr[x].cnt > 1) tr[x].cnt--;
else if (tr[x].l || tr[x].r) {
if (!tr[x].r || tr[tr[x].l].val > tr[tr[x].r].val) {
zig(x);
remove(tr[x].r, k);
}
else {
zag(x);
remove(tr[x].l, k);
}
}
else x = 0;
}
else if (k < tr[x].key) remove(tr[x].l, k);
else remove(tr[x].r, k);
pushup(x);
}
int query1(int x, int k) {
if (!x) return 0;
if (k == tr[x].key) return tr[tr[x].l].siz + 1;
else if (k < tr[x].key) return query1(tr[x].l, k);
else return tr[tr[x].l].siz + tr[x].cnt + query1(tr[x].r, k);
}
int query2(int x, int k) {
if (!x) return INF;
if (k <= tr[tr[x].l].siz) return query2(tr[x].l, k);
else if (k <= tr[tr[x].l].siz + tr[x].cnt) return tr[x].key;
else return query2(tr[x].r, k - tr[tr[x].l].siz - tr[x].cnt);
}
int pre(int x, int k) {
if (!x) return -INF;
if (k <= tr[x].key) return pre(tr[x].l, k);
else return max(tr[x].key, pre(tr[x].r, k));
}
int nxt(int x, int k) {
if (!x) return INF;
if (k >= tr[x].key) return nxt(tr[x].r, k);
else return min(tr[x].key, nxt(tr[x].l, k));
}
void solve() {
build();
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
int op, x;
cin >> op >> x;
if (op == 1) insert(root, x);
else if (op == 2) remove(root, x);
else if (op == 3) cout << query1(root, x) - 1 << '\n';
else if (op == 4) cout << query2(root, x + 1) << '\n';
else if (op == 5) cout << pre(root, x) << '\n';
else cout << nxt(root, x) << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
FHQ Treap
P3369 【模板】普通平衡树
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 1e5 + 10;
struct node {
int l, r, key, val, siz;
}tr[N];
int root=0, tot = 0;
void creatnode(int k) {
tr[++tot].key = k;
tr[tot].val = rand();
tr[tot].siz = 1;
}
void pushup(int x) {
tr[x].siz = tr[tr[x].l].siz + tr[tr[x].r].siz + 1;
}
void split(int x, int& l, int& r,int k) {
if (!x) {
l = r = 0;
return;
}
if (tr[x].key <= k) {
l = x;
split(tr[x].r, tr[x].r, r, k);
}
else {
r = x;
split(tr[x].l, l, tr[x].l, k);
}
pushup(x);
}
int merge(int x, int y) {
if (!x || !y) return x + y;
if (tr[x].val >= tr[y].val) {
tr[x].r = merge(tr[x].r, y);
pushup(x);
return x;
}
else {
tr[y].l = merge(x, tr[y].l);
pushup(y);
return y;
}
}
void insert(int k) {
int l, r;
split(root, l, r, k);
creatnode(k);
int p = merge(l, tot);
root = merge(p, r);
}
void remove(int k) {
int l, r, p;
split(root, l, r, k);
split(l, l, p, k-1);
p = merge(tr[p].l, tr[p].r);
root = merge(merge(l, p), r);
}
void rnk(int k) {
int l, r;
split(root, l, r, k - 1);
cout << tr[l].siz + 1 << '\n';
root = merge(l, r);
}
int kth(int x,int k) {
if (k == tr[tr[x].l].siz + 1) return tr[x].key;
else if (k <= tr[tr[x].l].siz) return kth(tr[x].l, k);
else return kth(tr[x].r, k - tr[tr[x].l].siz - 1);
}
void pre(int k) {
int l, r;
split(root, l, r, k - 1);
cout<> n;
for (int i = 1; i <= n; ++i) {
int op, x;
cin >> op >> x;
if (op == 1) insert(x);
else if (op == 2) remove(x);
else if (op == 3) rnk(x);
else if (op == 4) cout << kth(root,x) << '\n';
else if (op == 5) pre(x);
else nxt(x);
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
排名分裂P4008 [NOI2003] 文本编辑器
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 3e6 + 10;
struct node {
int l, r, val, siz;
char key;
}tr[N];
int root = 0, tot = 0,pos=0;
void creatnode(char k) {
tr[++tot].key = k;
tr[tot].val = rand();
tr[tot].siz = 1;
}
void pushup(int x) {
tr[x].siz = tr[tr[x].l].siz + tr[tr[x].r].siz + 1;
}
void split(int x, int& l, int& r, int k) {
if (!x) {
l = r = 0;
return;
}
if (tr[tr[x].l].siz+1 <= k) {
l = x;
split(tr[x].r, tr[x].r, r, k - tr[tr[x].l].siz - 1);
}
else {
r = x;
split(tr[x].l, l, tr[x].l, k);
}
pushup(x);
}
int merge(int x, int y) {
if (!x || !y) return x + y;
if (tr[x].val >= tr[y].val) {
tr[x].r = merge(tr[x].r, y);
pushup(x);
return x;
}
else {
tr[y].l = merge(x, tr[y].l);
pushup(y);
return y;
}
}
void insert(int len) {
int l, r;
split(root, l, r, pos);
for (int i = 1; i <= len; ++i) {
char ch = getchar();
while (ch < 32 || ch>126) ch = getchar();
creatnode(ch);
l = merge(l, tot);
}
root = merge(l, r);
}
void remove(int len) {
int l, r, p;
split(root, l, r, pos+len);
split(l, l, p, pos);
root = merge(l, r);
}
void inorder(int x) {
if (!x) return;
inorder(tr[x].l);
cout << tr[x].key;
inorder(tr[x].r);
}
void get(int len) {
int l, r,p;
split(root, l, r, pos+len);
split(l, l, p, pos);
inorder(p);
root = merge(merge(l, p), r);
}
void solve() {
srand(time(0));
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
string op;
int len;
cin >> op;
if (op[0] == 'M') cin >> pos;
else if (op[0] == 'I') {
cin >> len;
insert(len);
}
else if (op[0] == 'D') {
cin >> len;
remove(len);
}
else if (op[0] == 'G') {
cin >> len;
get(len);
cout << '\n';
}
else if (op[0] == 'P') pos--;
else pos++;
}
}
int main() {
//ios::sync_with_stdio(false);
//cin.tie(0);
//cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
P3391 【模板】文艺平衡树
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 1e5 + 10;
struct node {
int l, r, key, val, siz, tag;
}tr[N];
int root = 0, tot = 0;
void creatnode(int k) {
tr[++tot].key = k;
tr[tot].val = rand();
tr[tot].siz = 1;
}
void pushup(int x) {
tr[x].siz = tr[tr[x].l].siz + tr[tr[x].r].siz + 1;
}
void pushdown(int x) {
if (tr[x].tag) {
swap(tr[x].l, tr[x].r);
tr[tr[x].l].tag ^= 1;
tr[tr[x].r].tag ^= 1;
tr[x].tag = 0;
}
}
void split(int x, int& l, int& r, int k) {
if (!x) {
l = r = 0;
return;
}
pushdown(x);
if (tr[tr[x].l].siz + 1 <= k) {
l = x;
split(tr[x].r, tr[x].r, r, k - tr[tr[x].l].siz - 1);
}
else {
r = x;
split(tr[x].l, l, tr[x].l, k);
}
pushup(x);
}
int merge(int x, int y) {
if (!x || !y) return x + y;
if (tr[x].val >= tr[y].val) {
pushdown(x);
tr[x].r = merge(tr[x].r, y);
pushup(x);
return x;
}
else {
pushdown(y);
tr[y].l = merge(x, tr[y].l);
pushup(y);
return y;
}
}
void inorder(int x) {
if (!x) return;
pushdown(x);
inorder(tr[x].l);
cout << tr[x].key << " ";
inorder(tr[x].r);
}
void solve() {
srand(time(0));
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
creatnode(i);
root = merge(root, tot);
}
for (int i = 1; i <= m; ++i) {
int l, r, p, x, y;
cin >> x >> y;
split(root, l, r, y);
split(l, l, p, x - 1);
tr[p].tag ^= 1;
root = merge(merge(l, p), r);
}
inorder(root);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
P3835 【模板】可持久化平衡树
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 2 << 30 - 1;
const ll N = 5e5 + 10;
struct node {
int l, r, key, val, siz;
}tr[N << 7];
int root[N], tot = 0, idx = 0;
void creatnode(int k) {
tr[++tot].key = k;
tr[tot].val = rand();
tr[tot].siz = 1;
}
void pushup(int x) {
tr[x].siz = tr[tr[x].l].siz + tr[tr[x].r].siz + 1;
}
int clone(int x) {
++tot;
tr[tot] = tr[x];
return tot;
}
void split(int x, int& l, int& r, int k) {
if (!x) {
l = r = 0;
return;
}
if (tr[x].key <= k) {
l = clone(x);
split(tr[l].r, tr[l].r, r, k);
pushup(l);
}
else {
r = clone(x);
split(tr[r].l, l, tr[r].l, k);
pushup(r);
}
}
int merge(int x, int y) {
if (!x || !y) return x + y;
if (tr[x].val >= tr[y].val) {
tr[x].r = merge(tr[x].r, y);
pushup(x);
return x;
}
else {
tr[y].l = merge(x, tr[y].l);
pushup(y);
return y;
}
}
int kth(int x, int k) {
if (k <= tr[tr[x].l].siz) return kth(tr[x].l, k);
else if (k == tr[tr[x].l].siz + 1) return tr[x].key;
else return kth(tr[x].r, k - tr[tr[x].l].siz - 1);
}
void solve() {
srand(time(0));
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
int v, op, x, l, r, p;
cin >> v >> op >> x;
if (op == 1) {
split(root[v], l, r, x);
creatnode(x);
root[++idx] = merge(merge(l, tot), r);
}
else if (op == 2) {
split(root[v], l, r, x);
split(l, l, p, x - 1);
p = merge(tr[p].l, tr[p].r);
root[++idx] = merge(merge(l, p), r);
}
else if (op == 3) {
split(root[v], l, r, x - 1);
cout << tr[l].siz + 1 << '\n';
root[++idx] = merge(l, r);
}
else if (op == 4) {
cout << kth(root[v], x) << '\n';
root[++idx] = root[v];
}
else if (op == 5) {
split(root[v], l, r, x - 1);
if (!l) cout << -INF << '\n';
else cout << kth(l, tr[l].siz) << '\n';
root[++idx] = merge(l, r);
}
else {
split(root[v], l, r, x);
if (!r) cout << INF << '\n';
else cout << kth(r, 1) << '\n';
root[++idx] = merge(l, r);
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
P5055 【模板】可持久化文艺平衡树
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 2e5 + 10;
struct node {
ll l, r, key, val, sum, siz, tag;
}tr[N << 7];
ll root[N], tot = 0, idx = 0;
void creatnode(ll k) {
++tot;
tr[tot].key = tr[tot].sum = k;
tr[tot].val = rand();
tr[tot].siz = 1;
}
ll clone(ll x) {
++tot;
tr[tot] = tr[x];
return tot;
}
void pushup(ll x) {
tr[x].siz = tr[tr[x].l].siz + tr[tr[x].r].siz + 1;
tr[x].sum = tr[tr[x].l].sum + tr[tr[x].r].sum + tr[x].key;
}
void pushdown(ll x) {
if (tr[x].tag) {
if (tr[x].l) tr[x].l = clone(tr[x].l);
if (tr[x].r) tr[x].r = clone(tr[x].r);
swap(tr[x].l, tr[x].r);
tr[tr[x].l].tag ^= 1, tr[tr[x].r].tag ^= 1;
tr[x].tag = 0;
}
}
void split(ll x, ll& l, ll& r, ll k) {
if (!x) {
l = r = 0;
return;
}
pushdown(x);
if (tr[tr[x].l].siz + 1 <= k) {
l = clone(x);
split(tr[l].r, tr[l].r, r, k - tr[tr[x].l].siz - 1);
pushup(l);
}
else {
r = clone(x);
split(tr[r].l, l, tr[r].l, k);
pushup(r);
}
}
ll merge(ll x, ll y) {
if (!x || !y) return x + y;
if (tr[x].val >= tr[y].val) {
pushdown(x);
tr[x].r = merge(tr[x].r, y);
pushup(x);
return x;
}
else {
pushdown(y);
tr[y].l = merge(x, tr[y].l);
pushup(y);
return y;
}
}
void solve() {
srand(time(0));
ll n, last = 0;
cin >> n;
for (int i = 1; i <= n; ++i) {
ll v, op;
cin >> v >> op;
if (op == 1) {
ll p, x, L, R;
cin >> p >> x;
p ^= last, x ^= last;
split(root[v], L, R, p);
creatnode(x);
root[++idx] = merge(merge(L, tot), R);
}
else if (op == 2) {
ll p, L, R, tmp;
cin >> p;
p ^= last;
split(root[v], L, R, p);
split(L, L, tmp, p - 1);
root[++idx] = merge(L, R);
}
else if (op == 3) {
ll l, r, L, R, tmp;
cin >> l >> r;
l ^= last, r ^= last;
split(root[v], L, R, r);
split(L, L, tmp, l - 1);
tr[tmp].tag ^= 1;
root[++idx] = merge(merge(L, tmp), R);
}
else {
ll l, r, L, R, tmp;
cin >> l >> r;
l ^= last, r ^= last;
split(root[v], L, R, r);
split(L, L, tmp, l - 1);
last = tr[tmp].sum;
cout << last << '\n';
root[++idx] = merge(merge(L, tmp), R);
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
Splay
P4008 [NOI2003] 文本编辑器
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 4e6 + 10;
struct node {
char key;
int l, r, fa, siz;
}tr[N];
int root = 1, tot = 2;
char s[N];
void init() {
tr[1].siz = 2, tr[1].l = 2;
tr[2].siz = 1, tr[2].fa = 1;
}
void pushup(int x) {
tr[x].siz = tr[tr[x].l].siz + tr[tr[x].r].siz + 1;
}
void rotate(int x) {
int y = tr[x].fa, z = tr[y].fa;
int k = (x == tr[y].r);
if (k == 1) {
tr[y].r = tr[x].l;
tr[tr[x].l].fa = y;
tr[x].l = y;
}
else {
tr[y].l = tr[x].r;
tr[tr[x].r].fa = y;
tr[x].r = y;
}
tr[y].fa = x;
tr[x].fa = z;
if (z) {
if (tr[z].l == y) tr[z].l = x;
else tr[z].r = x;
}
pushup(y), pushup(x);
}
void splay(int x, int k) {
while (tr[x].fa != k) {
int y = tr[x].fa, z = tr[y].fa;
if (z != k) {
if ((x == tr[y].r) == (y == tr[z].r)) rotate(y);
else rotate(x);
}
rotate(x);
}
if (k == 0) root = x;
}
int build(int l,int r,int f) {
if (l > r) return 0;
int mid = (l + r) >> 1;
int cur = ++tot;
tr[cur].fa = f;
tr[cur].key = s[mid];
tr[cur].l = build(l, mid - 1, cur);
tr[cur].r = build(mid + 1, r, cur);
pushup(cur);
return cur;
}
int kth(int x, int k) {
if (k <= tr[tr[x].l].siz) return kth(tr[x].l, k);
else if (k == tr[tr[x].l].siz + 1) return x;
else return kth(tr[x].r, k - tr[tr[x].l].siz - 1);
}
void insert(int pos, int len) {
int l = kth(root, pos), r = kth(root, pos + 1);
splay(l, 0), splay(r, l);
tr[r].l = build(1,len,r);
pushup(r), pushup(l);
}
void remove(int x, int len) {
int l = kth(root, x), r = kth(root, x + len + 1);
splay(l, 0), splay(r, l);
tr[r].l = 0;
pushup(r), pushup(l);
}
void inorder(int x) {
if (!x) return;
inorder(tr[x].l);
cout << tr[x].key;
inorder(tr[x].r);
}
void solve() {
int n,len,pos=1;
cin >> n;
init();
for (int i = 1; i <= n; ++i) {
string op;
cin >> op;
if (op[0] == 'M') cin >> pos,pos++;
else if (op[0] == 'I') {
cin >> len;
for (int i = 1; i <= len; ++i) {
char ch = getchar();
while (ch < 32 || ch>126) ch = getchar();
s[i] = ch;
}
insert(pos, len);
}
else if (op[0] == 'D') {
cin >> len;
remove(pos, len);
}
else if (op[0] == 'G') {
cin >> len;
int l = kth(root, pos), r = kth(root, pos+len+1);
splay(l, 0), splay(r, l);
inorder(tr[r].l);
cout << '\n';
}
else if (op[0] == 'P') pos--;
else pos++;
}
}
int main() {
//ios::sync_with_stdio(false);
//cin.tie(0);
//cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
P3391 【模板】文艺平衡树
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 1e5 + 10;
struct node {
int l, r,fa, key, siz, tag;
}tr[N];
int root = 0, tot = 0,n,m;
void creatnode(int k,int p) {
tr[++tot].key = k;
tr[tot].fa = p;
tr[tot].siz = 1;
}
void pushup(int x) {
tr[x].siz = tr[tr[x].l].siz + tr[tr[x].r].siz + 1;
}
void pushdown(int x) {
if (tr[x].tag) {
swap(tr[x].l, tr[x].r);
tr[tr[x].l].tag ^= 1;
tr[tr[x].r].tag ^= 1;
tr[x].tag = 0;
}
}
void rotate(int x) {
int y = tr[x].fa, z = tr[y]. fa;
int k = (tr[y].r == x);
if (k == 1) {
tr[y].r = tr[x].l;
tr[tr[x].l].fa = y;
tr[x].l = y;
}
else {
tr[y].l = tr[x].r;
tr[tr[x].r].fa = y;
tr[x].r = y;
}
tr[y].fa = x;
tr[x].fa = z;
if (tr[z].l == y) tr[z].l = x;
else tr[z].r = x;
pushup(y), pushup(x);
}
void splay(int x, int k) {
while (tr[x].fa != k) {
int y = tr[x].fa, z = tr[y].fa;
if (z != k) {
if ((tr[y].r == x) == (tr[z].r == y)) rotate(y);
else rotate(x);
}
rotate(x);
}
if (k == 0) root = x;
}
void insert(int k) {
int x = root, p = 0;
while (x) {
p = x;
if (tr[x].key < k) x = tr[x].r;
else x = tr[x].l;
}
creatnode(k,p);
if (p) {
if (k > tr[p].key) tr[p].r = tot;
else tr[p].l = tot;
}
splay(tot, 0);
}
int kth(int x,int k) {
pushdown(x);
if (k <= tr[tr[x].l].siz) return kth(tr[x].l, k);
else if (k == tr[tr[x].l].siz + 1) return x;
else return kth(tr[x].r, k - tr[tr[x].l].siz - 1);
}
void inorder(int x) {
if (!x) return;
pushdown(x);
inorder(tr[x].l);
if (tr[x].key >= 1 && tr[x].key <= n) cout << tr[x].key << " ";
inorder(tr[x].r);
}
void solve() {
cin >> n >> m;
for (int i = 0; i <= n + 1; ++i) insert(i);
for (int i = 1; i <= m; ++i) {
int l, r;
cin >> l >> r;
l = kth(root,l), r = kth(root,r + 2);
splay(l, 0), splay(r, l);
tr[tr[r].l].tag ^= 1;
}
inorder(root);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
笛卡尔树
P5854 【模板】笛卡尔树
建树
RMQ为区间端点LCA的值
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e9;
const ll N = 1e7 + 10;
struct node {
int l, r, val, fa;
}tr[N];
int read() {
int res = 0;
char ch = getchar();
while (ch < '0' || ch>'9') ch = getchar();
while (ch >= '0' && ch <= '9') { res = (res << 3) + (res << 1) + (ch ^ 48); ch = getchar(); }
return res;
}
void build(int n) {
for (int i = 1; i <= n; ++i) {
int p = i - 1;
while (tr[p].val > tr[i].val) p = tr[p].fa;
tr[i].l = tr[p].r;
tr[tr[p].r].fa = i;
tr[p].r = i;
tr[i].fa = p;
}
}
void solve() {
ll n, ans1 = 0, ans2 = 0;
n=read();
for (int i = 1; i <= n; ++i) tr[i].val=read();
tr[0].val = -INF;
build(n);
for (int i = 1; i <= n; ++i) {
ans1 ^= 1ll*i * (tr[i].l + 1);
ans2 ^= 1ll*i * (tr[i].r + 1);
}
cout << ans1 << " " << ans2;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
线段树套平衡树
P3380 【模板】二逼平衡树(树套树)
排名为k的值
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 2147483647;
const ll N = 2e6 + 10;
struct tree {
int l, r, siz, key, val;
}tr[N];
int a[N], root[N], tot = 0;
inline int read() {
int res = 0;
char ch = getchar();
while (ch < '0' || ch>'9') ch = getchar();
while (ch >= '0' && ch <= '9') { res = (res << 3) + (res << 1) + (ch ^ 48); ch = getchar(); }
return res;
}
inline void pushup(int x) {
tr[x].siz = tr[tr[x].l].siz + tr[tr[x].r].siz + 1;
}
inline void creatnode(int k) {
tr[++tot].key = k;
tr[tot].val = rand();
tr[tot].siz = 1;
}
inline void split(int x, int& l, int& r, int k) {
if (!x) {
l = r = 0;
return;
}
if (tr[x].key <= k) {
l = x;
split(tr[x].r, tr[x].r, r, k);
}
else {
r = x;
split(tr[x].l, l, tr[x].l, k);
}
pushup(x);
}
inline int merge(int x, int y) {
if (!x || !y) return x + y;
if (tr[x].val >= tr[y].val) {
tr[x].r = merge(tr[x].r, y);
pushup(x);
return x;
}
else {
tr[y].l = merge(x, tr[y].l);
pushup(y);
return y;
}
}
inline void insert(int& rt, int k) {
int l, r;
split(rt, l, r, k);
creatnode(k);
rt = merge(merge(l, tot), r);
}
inline void remove(int& rt, int k) {
int l, r, p;
split(rt, l, r, k);
split(l, l, p, k - 1);
p = merge(tr[p].l, tr[p].r);
rt = merge(merge(l, p), r);
}
inline int rnk(int& rt, int k) {
int u = rt, res = 0;
while (u) {
if (tr[u].key < k) res += tr[tr[u].l].siz + 1, u = tr[u].r;
else u = tr[u].l;
}
return res;
}
inline int kth(int x, int k) {
if (k == tr[tr[x].l].siz + 1) return tr[x].key;
else if (k <= tr[tr[x].l].siz) return kth(tr[x].l, k);
else return kth(tr[x].r, k - tr[tr[x].l].siz - 1);
}
inline int pre(int& rt, int k) {
int l, r;
split(rt, l, r, k - 1);
int res = kth(l, tr[l].siz);
rt = merge(l, r);
return res;
}
inline int nxt(int& rt, int k) {
int l, r;
split(rt, l, r, k);
int res = kth(r, 1);
rt = merge(l, r);
return res;
}
inline void build(int x, int l, int r) {
insert(root[x], -INF), insert(root[x], INF);
for (register int i = l; i <= r; ++i) insert(root[x], a[i]);
int mid = l + r >> 1;
if (l == r) return;
build(x << 1, l, mid);
build(x << 1 | 1, mid + 1, r);
}
inline void modify(int x, int l, int r, int p, int k) {
remove(root[x], a[p]);
insert(root[x], k);
if (l == r) return;
int mid = l + r >> 1;
if (p <= mid) modify(x << 1, l, mid, p, k);
else modify(x << 1 | 1, mid + 1, r, p, k);
}
inline int query(int x, int l, int r, int ql, int qr, int k) {
if (ql <= l && qr >= r) return rnk(root[x], k) - 1;
int res = 0;
int mid = l + r >> 1;
if (ql <= mid) res += query(x << 1, l, mid, ql, qr, k);
if (qr > mid) res += query(x << 1 | 1, mid + 1, r, ql, qr, k);
return res;
}
inline int querypre(int x, int l, int r, int ql, int qr, int k) {
if (ql <= l && qr >= r) return pre(root[x], k);
int res = -INF;
int mid = l + r >> 1;
if (ql <= mid) res = max(res, querypre(x << 1, l, mid, ql, qr, k));
if (qr > mid) res = max(res, querypre(x << 1 | 1, mid + 1, r, ql, qr, k));
return res;
}
inline int querynxt(int x, int l, int r, int ql, int qr, int k) {
if (ql <= l && qr >= r) return nxt(root[x], k);
int res = INF;
int mid = l + r >> 1;
if (ql <= mid) res = min(res, querynxt(x << 1, l, mid, ql, qr, k));
if (qr > mid) res = min(res, querynxt(x << 1 | 1, mid + 1, r, ql, qr, k));
return res;
}
inline void solve() {
srand(time(0));
int n, m;
n = read(), m = read();
for (register int i = 1; i <= n; ++i) a[i] = read();
build(1, 1, n);
for (int i = 1; i <= m; ++i) {
int op, k;
op = read();
if (op == 1) {
int l, r;
l = read(), r = read(), k = read();
cout << query(1, 1, n, l, r, k) + 1 << '\n';
}
else if (op == 2) {
int l, r;
l = read(), r = read(), k = read();
int L = 1, R = 1e8;
while (L <= R) {
int mid = L + R >> 1;
if (query(1, 1, n, l, r, mid) + 1 <= k) L = mid + 1;
else R = mid - 1;
}
cout << R << '\n';
}
else if (op == 3) {
int pos;
pos = read(), k = read();
modify(1, 1, n, pos, k);
a[pos] = k;
}
else if (op == 4) {
int l, r;
l = read(), r = read(), k = read();
cout << querypre(1, 1, n, l, r, k) << '\n';
}
else {
int l, r;
l = read(), r = read(), k = read();
cout << querynxt(1, 1, n, l, r, k) << '\n';
}
}
}
int main() {
//ios::sync_with_stdio(false);
//cin.tie(0);
//cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
KD树
最近邻点hdu2966 In case of failure
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 1e5 + 10;
const int k = 2;
struct Point {
ll dim[k];
}p[N], tr[N];
ll ans, cur;
bool cmp(Point a, Point b) {
return a.dim[cur] < b.dim[cur];
}
ll sq(ll x) {
return x * x;
}
ll dis(Point a, Point b) {
return sq(a.dim[0] - b.dim[0]) + sq(a.dim[1] - b.dim[1]);
}
void build(int l, int r, int dep) {
if (l >= r) return;
int mid = l + r >> 1;
cur = dep;
nth_element(tr + l, tr + mid, tr + r, cmp);
build(l, mid, (dep + 1) % k);
build(mid + 1, r, (dep + 1) % k);
}
void query(int l, int r, int dep, Point a) {
if (l >= r) return;
int mid = l + r >> 1;
ll d = dis(tr[mid], a);
if (!ans || d && ans > d) ans = d;
if (a.dim[dep] > tr[mid].dim[dep]) {
query(mid + 1, r, (dep + 1) % k, a);
if (ans > sq(a.dim[dep] - tr[mid].dim[dep]))
query(l, mid, (dep + 1) % k, a);
}
else {
query(l, mid, (dep + 1) % k, a);
if (ans > sq(a.dim[dep] - tr[mid].dim[dep]))
query(mid + 1, r, (dep + 1) % k, a);
}
}
void solve() {
int n;
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> p[i].dim[0] >> p[i].dim[1];
tr[i] = p[i];
}
build(0, n, 0);
for (int i = 0; i < n; ++i) {
ans = 0;
query(0, n, 0, p[i]);
cout << ans << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
//_t = 1;
cin >> _t;
while (_t--) {
solve();
}
return 0;
}
区间查询P4148 简单题
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 2e5 + 10;
const double alpha = 0.75;
struct point {
int dim[2], k;
point() {}
point(int x, int y, int key) {
dim[0] = x;
dim[1] = y;
k = key;
}
}order[N];
struct node {
int l, r, sum, siz, mn[2], mx[2];
point p;
}tr[N];
int root, tot, cur, top, st[N], cnt;
bool cmp(point a, point b) {
return a.dim[cur] < b.dim[cur];
}
void pushup(int u) {
for (int i = 0; i < 2; ++i) {
tr[u].mn[i] = tr[u].mx[i] = tr[u].p.dim[i];
if (tr[u].l) {
tr[u].mn[i] = min(tr[u].mn[i], tr[tr[u].l].mn[i]);
tr[u].mx[i] = max(tr[u].mx[i], tr[tr[u].l].mx[i]);
}
if (tr[u].r) {
tr[u].mn[i] = min(tr[u].mn[i], tr[tr[u].r].mn[i]);
tr[u].mx[i] = max(tr[u].mx[i], tr[tr[u].r].mx[i]);
}
}
tr[u].sum = tr[tr[u].l].sum + tr[tr[u].r].sum + tr[u].p.k;
tr[u].siz = tr[tr[u].l].siz + tr[tr[u].r].siz + 1;
}
void slap(int u) {
if (!u) return;
slap(tr[u].l);
order[++cnt] = tr[u].p;
st[++top] = u;
slap(tr[u].r);
}
int build(int l, int r, int d) {
if (l > r) return 0;
int u;
if (top) u = st[top--];
else u = ++tot;
int mid = l + r >> 1;
cur = d;
nth_element(order + l, order + mid, order + r + 1, cmp);
tr[u].p = order[mid];
tr[u].l = build(l, mid - 1, d ^ 1);
tr[u].r = build(mid + 1, r, d ^ 1);
pushup(u);
return u;
}
bool notbalance(int u) {
if (tr[tr[u].l].siz > alpha * tr[u].siz || tr[tr[u].r].siz > alpha * tr[u].siz) return 1;
else return 0;
}
void insert(int& u, point x, int d) {
if (!u) {
if (top) u = st[top--];
else u = ++tot;
tr[u].l = tr[u].r = 0;
tr[u].p = x;
pushup(u);
return;
}
if (x.dim[d] <= tr[u].p.dim[d]) insert(tr[u].l, x, d ^ 1);
else insert(tr[u].r, x, d ^ 1);
pushup(u);
if (notbalance(u)) {
cnt = 0;
slap(u);
u = build(1, tr[u].siz, d);
}
}
int query(int u, int x1, int y1, int x2, int y2) {
if (!u) return 0;
int xx1 = tr[u].mn[0], yy1 = tr[u].mn[1], xx2 = tr[u].mx[0], yy2 = tr[u].mx[1];
if (x1 <= xx1 && x2 >= xx2 && y1 <= yy1 && y2 >= yy2) return tr[u].sum;
if (x1 > xx2 || x2yy2 || y2 < yy1) return 0;
int ans = 0;
xx1 = tr[u].p.dim[0], yy1 = tr[u].p.dim[1], xx2 = tr[u].p.dim[0], yy2 = tr[u].p.dim[1];
if (x1 <= xx1 && x2 >= xx2 && y1 <= yy1 && y2 >= yy2) ans += tr[u].p.k;
ans += query(tr[u].l, x1, y1, x2, y2) + query(tr[u].r, x1, y1, x2, y2);
return ans;
}
void solve() {
int n, ans = 0;
cin >> n;
while (1) {
int op;
cin >> op;
if (op == 1) {
int x, y, k;
cin >> x >> y >> k;
x ^= ans, y ^= ans, k ^= ans;
insert(root, point(x, y, k), 0);
}
else if (op == 2) {
int x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
x1 ^= ans, y1 ^= ans, x2 ^= ans, y2 ^= ans;
ans = query(root, x1, y1, x2, y2);
cout << ans << '\n';
}
else break;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
K近邻 P2093 [国家集训队]JZPFAR
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 1e5 + 10;
struct point {
ll dim[2], id;
}p[N];
struct tree {
ll l, r, mx[2], mn[2], id;
point p;
}tr[N];
struct node {
ll dis, id;
bool operator<(const node a)const {
return dis == a.dis ? id < a.id : dis > a.dis;
}
};
priority_queue q;
int root, tot, now;
bool cmp(point a, point b) {
return a.dim[now] < b.dim[now];
}
void pushup(int x) {
for (int i = 0; i < 2; ++i) {
tr[x].mn[i] = tr[x].mx[i] = tr[x].p.dim[i];
if (tr[x].l) {
tr[x].mn[i] = min(tr[x].mn[i], tr[tr[x].l].mn[i]);
tr[x].mx[i] = max(tr[x].mx[i], tr[tr[x].l].mx[i]);
}
if (tr[x].r) {
tr[x].mn[i] = min(tr[x].mn[i], tr[tr[x].r].mn[i]);
tr[x].mx[i] = max(tr[x].mx[i], tr[tr[x].r].mx[i]);
}
}
}
int build(int l, int r, int d) {
if (l > r) return 0;
int x = ++tot;
int mid = l + r >> 1;
now = d;
nth_element(p + l, p + mid, p + r + 1, cmp);
tr[x].p = p[mid];
tr[x].id = p[mid].id;
tr[x].l = build(l, mid - 1, d ^ 1);
tr[x].r = build(mid + 1, r, d ^ 1);
pushup(x);
return x;
}
ll sq(ll x) {
return x * x;
}
ll dis(point a, point b) {
return sq(a.dim[0] - b.dim[0]) + sq(a.dim[1] - b.dim[1]);
}
ll getdis(int x, point a) {
ll res = 0;
for (int i = 0; i < 2; ++i) {
res += max(sq(a.dim[i] - tr[x].mx[i]), sq(a.dim[i] - tr[x].mn[i]));
}
return res;
}
void query(int x, point a) {
if (!x) return;
ll res = dis(tr[x].p, a);
if (res > q.top().dis || res == q.top().dis && tr[x].id < q.top().id) {
q.pop();
q.push({ res,tr[x].id });
}
ll ld = INF, rd = INF;
if (tr[x].l) ld = getdis(tr[x].l, a);
if (tr[x].r) rd = getdis(tr[x].r, a);
if (ld < rd) {
if (rd >= q.top().dis) query(tr[x].r, a);
if (ld >= q.top().dis) query(tr[x].l, a);
}
else {
if (ld > q.top().dis) query(tr[x].l, a);
if (rd > q.top().dis) query(tr[x].r, a);
}
}
void solve() {
int n, m, k;
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> p[i].dim[0] >> p[i].dim[1];
p[i].id = i;
}
root = build(1, n, 0);
cin >> m;
for (int i = 1; i <= m; ++i) {
point a;
cin >> a.dim[0] >> a.dim[1] >> k;
while (!q.empty()) q.pop();
for (int j = 1; j <= k; ++j) q.push({ -1,0 });
query(root, a);
cout << q.top().id << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin >> _t;
while (_t--) {
solve();
}
return 0;
}
LCT
P3690 【模板】动态树(Link Cut Tree)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 998244353;
const ll INF = 1e18;
const ll N = 1e5 + 10;
struct node {
int l, r,fa, key, tag, sum;
}tr[N];
int st[N];
void pushup(int x) {
tr[x].sum = tr[tr[x].l].sum ^ tr[tr[x].r].sum ^ tr[x].key;
}
void pushtag(int x) {
swap(tr[x].l, tr[x].r);
tr[x].tag ^= 1;
}
void pushdown(int x) {
if (tr[x].tag) {
pushtag(tr[x].l);
pushtag(tr[x].r);
tr[x].tag = 0;
}
}
bool isroot(int x) {
return tr[tr[x].fa].l != x && tr[tr[x].fa].r != x;
}
void rotate(int x) {
int y = tr[x].fa, z = tr[y].fa;
int k = (x == tr[y].r);
if (!isroot(y)) {
if (tr[z].l == y) tr[z].l = x;
else tr[z].r = x;
}
if (k == 1) {
tr[y].r = tr[x].l;
tr[tr[x].l].fa = y;
tr[x].l = y;
}
else {
tr[y].l = tr[x].r;
tr[tr[x].r].fa = y;
tr[x].r = y;
}
tr[y].fa = x;
tr[x].fa = z;
pushup(y), pushup(x);
}
void splay(int x) {
int top = 0, p = x;
st[++top] = p;
while (!isroot(p)) st[++top] = p = tr[p].fa;
while (top) pushdown(st[top--]);
while (!isroot(x)) {
int y = tr[x].fa, z = tr[y].fa;
if (!isroot(y)) {
if ((tr[y].r == x) == (tr[z].r == y)) rotate(y);
else rotate(x);
}
rotate(x);
}
}
void access(int x) {
int z = x;
for (int y = 0; x; y = x, x = tr[x].fa){
splay(x);
tr[x].r = y;
pushup(x);
}
splay(z);
}
void makeroot(int x) {
access(x);
pushtag(x);
}
int findroot(int x) {
access(x);
while (tr[x].l) x = tr[x].l;
splay(x);
return x;
}
void split(int x, int y) {
makeroot(x);
access(y);
}
void link(int x, int y) {
makeroot(x);
if (findroot(y) != x) tr[x].fa = y;
}
void cut(int x, int y) {
makeroot(x);
if (findroot(y) == x && tr[y].fa == x && !tr[y].l) {
tr[x].r = tr[y].fa = 0;
pushup(x);
}
}
void solve() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i) cin >> tr[i].key;
for (int i = 1; i <= m; ++i) {
int op, x, y;
cin >> op >> x >> y;
if (op == 0) {
split(x, y);
cout << tr[y].sum << '\n';
}
else if (op == 1) link(x, y);
else if (op == 2) cut(x, y);
else {
splay(x);
tr[x].key = y;
pushup(x);
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin >> _t;
while (_t--) {
solve();
}
return 0;
}
左偏树
P3377 【模板】左偏树(可并堆)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 1e5 + 10;
struct {
int l, r, key, dis;
bool del;
}tr[N];
int f[N];
bool cmp(int x, int y) {
if (tr[x].key != tr[y].key) return tr[x].key < tr[y].key;
else return x < y;
}
int find(int x) {
if (f[x] == x) return x;
else return f[x] = find(f[x]);
}
int merge(int x, int y) {
if (!x || !y) return x + y;
if (!cmp(x, y)) swap(x, y);
tr[x].r = merge(tr[x].r, y);
if (tr[tr[x].l].dis < tr[tr[x].r].dis) swap(tr[x].l, tr[x].r);
tr[x].dis = tr[tr[x].r].dis + 1;
return x;
}
void solve() {
int n, m;
cin >> n >> m;
tr[0].key = 2e9;
for (int i = 1; i <= n; ++i) {
cin >> tr[i].key;
tr[i].dis = 1;
f[i] = i;
}
for (int i = 1; i <= m; ++i) {
int op;
cin >> op;
if (op == 1) {
int x, y;
cin >> x >> y;
if (tr[x].del || tr[y].del) continue;
x = find(x), y = find(y);
if (x != y) {
if (!cmp(x, y)) swap(x, y);
merge(x, y);
f[y] = x;
}
}
else {
int x;
cin >> x;
if (tr[x].del) {
cout << -1 << '\n';
continue;
}
x = find(x);
cout << tr[x].key << '\n';
if (!cmp(tr[x].l, tr[x].r)) swap(tr[x].l, tr[x].r);
merge(tr[x].l, tr[x].r);
tr[x].del = 1;
f[x] = tr[x].l;
f[tr[x].l] = tr[x].l;
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
DLX(精确覆盖问题)
AcWing1067精确覆盖问题
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 6e3 + 10;
struct node {
int l, r, u, d, row, col;
}p[N];
int n, m, cnt[N], tot, ans[N], top;
void init() {
for (int i = 0; i <= m; ++i) {
p[i].l = i - 1, p[i].r = i + 1;
p[i].u = p[i].d = i;
}
p[0].l = m, p[m].r = 0;
tot = m + 1;
}
void add(int& hh, int& tt, int x, int y) {
p[tot].row = y, p[tot].col = x, cnt[x]++;
p[tot].l = hh, p[tot].r = tt;
p[hh].r = p[tt].l = tot;
p[tot].u = x, p[tot].d = p[x].d;
p[x].d = p[p[x].d].u = tot;
tt = tot++;
}
void remove(int x) {
p[p[x].l].r = p[x].r, p[p[x].r].l = p[x].l;
for (int i = p[x].d; i != x; i = p[i].d) {
for (int j = p[i].r; j != i; j = p[j].r) {
cnt[p[j].col]--;
p[p[j].d].u = p[j].u, p[p[j].u].d = p[j].d;
}
}
}
void resume(int x) {
for (int i = p[x].u; i != x; i = p[i].u) {
for (int j = p[i].l; j != i; j = p[j].l) {
cnt[p[j].col]++;
p[p[j].d].u = j, p[p[j].u].d = j;
}
}
p[p[x].l].r = x, p[p[x].r].l = x;
}
bool dfs() {
if (!p[0].r) return 1;
int mn = p[0].r;
for (int i = p[0].r; i; i = p[i].r) {
if (cnt[i] < cnt[mn]) mn = i;
}
remove(mn);
for (int i = p[mn].d; i != mn; i = p[i].d) {
ans[++top] = p[i].row;
for (int j = p[i].r; j != i; j = p[j].r) remove(p[j].col);
if (dfs()) return 1;
for (int j = p[i].l; j != i; j = p[j].l) resume(p[j].col);
top--;
}
resume(mn);
return 0;
}
void solve() {
cin >> n >> m;
init();
for (int i = 1; i <= n; ++i) {
int hh = tot, tt = tot;
for (int j = 1; j <= m; ++j) {
int x;
cin >> x;
if (x) add(hh, tt, j, i);
}
}
if (dfs()) {
for (int i = 1; i <= top; ++i) cout << ans[i] << " ";
}
else cout << "No Solution!";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
DLX(重复覆盖问题)
AcWing2713重复覆盖问题
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 1e4 + 10;
struct node {
int l, r, u, d, row, col;
}p[N];
int n, m, cnt[N], tot, ans[N], st[110];
inline void init() {
for (register int i = 0; i <= m; ++i) {
p[i].l = i - 1, p[i].r = i + 1;
p[i].col = p[i].u = p[i].d = i;
}
p[0].l = m, p[m].r = 0;
tot = m + 1;
}
inline void add(int& hh, int& tt, int x, int y) {
p[tot].col = x, p[tot].row = y, cnt[x]++;
p[tot].u = x, p[tot].d = p[x].d;
p[x].d = p[p[x].d].u = tot;
p[hh].r = p[tt].l = tot;
p[tot].l = hh, p[tot].r = tt;
tt = tot++;
}
inline int h() {
int cnt = 0;
for (register int i = 1; i <= m; ++i) st[i] = 0;
for (register int i = p[0].r; i; i = p[i].r) {
if (st[p[i].col]) continue;
cnt++;
st[p[i].col] = 1;
for (register int j = p[i].d; j != i; j = p[j].d) {
for (register int k = p[j].r; k != j; k = p[k].r) st[p[k].col] = 1;
}
}
return cnt;
}
inline void remove(int x) {
for (register int i = p[x].d; i != x; i = p[i].d) {
p[p[i].l].r = p[i].r, p[p[i].r].l = p[i].l;
}
}
inline void resume(int x) {
for (register int i = p[x].u; i != x; i = p[i].u) {
p[p[i].l].r = i, p[p[i].r].l = i;
}
}
inline bool dfs(int k, int dep) {
if (k + h() > dep) return 0;
if (!p[0].r) return 1;
int mn = p[0].r;
for (register int i = p[0].r; i; i = p[i].r) {
if (cnt[i] < cnt[mn]) mn = i;
}
for (register int i = p[mn].d; i != mn; i = p[i].d) {
ans[k] = p[i].row;
remove(i);
for (register int j = p[i].r; j != i; j = p[j].r) remove(j);;
if (dfs(k + 1, dep)) return 1;
for (register int j = p[i].l; j != i; j = p[j].l) resume(j);
resume(i);
}
return 0;
}
inline void solve() {
cin >> n >> m;
init();
for (register int i = 1; i <= n; ++i) {
int hh = tot, tt = tot;
for (register int j = 1; j <= m; ++j) {
int x;
cin >> x;
if (x) add(hh, tt, j, i);
}
}
int dep = 0;
while (!dfs(0, dep)) dep++;
cout << dep << '\n';
for (int i = 0; i < dep; ++i) cout << ans[i] << " ";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
CDQ分治
P3810 【模板】三维偏序(陌上花开)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 2e5 + 10;
struct node {
int a, b, c, cnt, ans;
bool operator<(node t) {
if (a != t.a) return a < t.a;
else if (b != t.b) return b < t.b;
else return c < t.c;
}
bool operator==(node t) {
return a == t.a && b == t.b && c == t.c;
}
}p[N], tmp[N];
int n, k, ans[N], c[N];
int lowbit(int x) {
return x & -x;
}
void add(int x, int y) {
for (; x <= k; x += lowbit(x)) c[x] += y;
}
int query(int x) {
int res = 0;
for (; x; x -= lowbit(x)) res += c[x];
return res;
}
void mergesort(int l, int r) {
if (l >= r) return;
int mid = l + r >> 1;
mergesort(l, mid), mergesort(mid + 1, r);
int L = l, R = mid + 1;
int len = 0;
while (L <= mid && R <= r) {
if (p[L].b <= p[R].b) add(p[L].c, p[L].cnt), tmp[++len] = p[L], L++;
else p[R].ans += query(p[R].c), tmp[++len] = p[R], R++;
}
while (L <= mid) add(p[L].c, p[L].cnt), tmp[++len] = p[L], L++;
while (R <= r) p[R].ans += query(p[R].c), tmp[++len] = p[R], R++;
for (int i = l; i <= mid; ++i) add(p[i].c, -p[i].cnt);
for (int i = l, j = 1; j <= len; ++i, ++j) p[i] = tmp[j];
}
void solve() {
cin >> n >> k;
for (int i = 1; i <= n; ++i) {
cin >> p[i].a >> p[i].b >> p[i].c;
p[i].cnt = 1;
}
sort(p + 1, p + n + 1);
int len = 0;
for (int i = 1; i <= n; ++i) {
if (p[i] == p[len]) p[len].cnt++;
else p[++len] = p[i];
}
mergesort(1, len);
for (int i = 1; i <= len; ++i) ans[p[i].ans + p[i].cnt - 1] += p[i].cnt;
for (int i = 0; i < n; ++i) cout << ans[i] << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
01Trie
P4551 最长异或路径
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 2e6 + 10;
struct edge {
int u, v, w;
};
vector >e(N);
int tr[N][2], tot, sum[N];
void insert(int k) {
int p = 0;
for (int i = 30; i >= 0; --i) {
int x = (k >> i) & 1;
if (!tr[p][x]) tr[p][x] = ++tot;
p = tr[p][x];
}
}
int query(int k) {
int p = 0, res = 0;
for (int i = 30; i >= 0; --i) {
int x = (k >> i) & 1;
if (tr[p][!x]) {
res += (1 << i);
p = tr[p][!x];
}
else p = tr[p][x];
}
return res;
}
void dfs(int x, int fa) {
for (auto i : e[x]) {
if (i.v == fa) continue;
sum[i.v] = sum[x] ^ i.w;
insert(sum[i.v]);
dfs(i.v, x);
}
}
void solve() {
int n;
cin >> n;
for (int i = 1; i < n; ++i) {
int u, v, w;
cin >> u >> v >> w;
e[u].push_back({ u,v,w });
e[v].push_back({ v,u,w });
}
dfs(1, 0);
insert(0);
int ans = 0;
for (int i = 1; i <= n; ++i) {
ans = max(ans, query(sum[i]));
}
cout << ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin >> _t;
while (_t--) {
solve();
}
return 0;
}
可持久化01Trie
P4735 最大异或和
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 1e8 + 10;
int tr[N][2], tot, pre, root[N], cnt[N];
void insert(int rt, int k) {
int p = tot, q = rt;
for (int i = 24; i >= 0; --i) {
tr[p][0] = tr[q][0], tr[p][1] = tr[q][1];
int x = (k >> i) & 1;
tr[p][x] = ++tot;
p = tr[p][x], q = tr[q][x];
cnt[p] = cnt[q] + 1;
}
}
int query(int p, int q, int k) {
int res = 0;
for (int i = 24; i >= 0; --i) {
int x = (k >> i) & 1;
if (cnt[tr[q][!x]] > cnt[tr[p][!x]]) {
res += (1 << i);
p = tr[p][!x], q = tr[q][!x];
}
else p = tr[p][x], q = tr[q][x];
}
return res;
}
void solve() {
int n, m;
cin >> n >> m;
root[0] = ++tot;
insert(0, 0);
for (int i = 1; i <= n; ++i) {
int x;
cin >> x;
pre ^= x;
root[i] = ++tot;
insert(root[i - 1], pre);
}
for (int i = 1; i <= m; ++i) {
char op;
cin >> op;
if (op == 'A') {
int x;
cin >> x;
++n;
pre ^= x;
root[n] = ++tot;
insert(root[n - 1], pre);
}
else {
int l, r, x;
cin >> l >> r >> x;
if (l == 1) cout << query(0, root[r - 1], pre ^ x) << '\n';
else cout << query(root[l - 2], root[r - 1], pre ^ x) << '\n';
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin >> _t;
while (_t--) {
solve();
}
return 0;
}
树同构
P5043 【模板】树同构([BJOI2015]树的同构)
树哈希
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 55;
vector >e(N);
ll ans[N][N];
ll mask = 2333;
ll shift(ll x) {
x ^= mask;
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
x ^= mask;
return x;
}
ll Hash(int x, int fa) {
ll son[N], cnt = 0, ans = 0;
for (int i : e[x]) {
if (i == fa) continue;
son[++cnt] = Hash(i, x);
}
sort(son + 1, son + cnt + 1);
for (int i = 1; i <= cnt; ++i) ans = ans * 2333 + son[i];
return ans * 2333 + 1;
//for (int i = 1; i <= cnt; ++i) ans += shift(son[i]);
//return ans + 1;
}
void solve() {
int m;
cin >> m;
for (int i = 1; i <= m; ++i) {
e.clear();
e.resize(N);
int n;
cin >> n;
for (int j = 1; j <= n; ++j) {
int u;
cin >> u;
if (u) e[u].push_back(j), e[j].push_back(u);
}
for (int j = 1; j <= n; ++j) ans[i][j] = Hash(j, 0);
sort(ans[i] + 1, ans[i] + n + 1);
for (int j = 1; j <= i; ++j) {
int k;
for (k = 1; k <= n; ++k) {
if (ans[j][k] != ans[i][k]) break;
}
if (k > n) {
cout << j << '\n';
break;
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
AHU算法
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define P pair
const double eps = 1e-8;
const ll mod = 1e9 + 7;
const ll INF = 1e18;
const ll N = 55;
vector >e(N);
int m, n, mn,siz[N], zx[N], cnt;
string f[N], son[N], tmp, ans[N];
void dfs1(int x, int fa) {
siz[x] = 1;
int tmp = 0;
for (int i : e[x]) {
if (i == fa) continue;
dfs1(i, x);
siz[x] += siz[i];
tmp = max(tmp, siz[i]);
}
tmp = max(tmp, n - siz[x]);
if (tmp < mn) {
mn = tmp;
cnt = 0;
zx[++cnt] = x;
}
else if (tmp == mn) zx[++cnt] = x;
}
void dfs2(int x, int fa) {
f[x] = "0";
for (int i : e[x]) {
if (i == fa) continue;
dfs2(i, x);
}
int tot = 0;
for (int i : e[x]) {
if (i == fa) continue;
son[++tot] = f[i];
}
sort(son + 1, son + tot + 1);
for (int i = 1; i <= tot; ++i) f[x] += son[i];
f[x] += "1";
return;
}
void solve() {
cin >> m;
for (int i = 1; i <= m; ++i) {
e.clear();
e.resize(N);
tmp = "1", mn = 0x3f3f3f3f, cnt = 0;
cin >> n;
for (int j = 1; j <= n; ++j) {
int u;
cin >> u;
if (u) e[u].push_back(j), e[j].push_back(u);
}
dfs1(1, 0);
for (int j = 1; j <= cnt; ++j) {
dfs2(zx[j], 0);
tmp = min(tmp, f[zx[j]]);
}
ans[i] = tmp;
for (int j = 1; j <= i; ++j) {
if (ans[j] == ans[i]) {
cout << j << '\n';
break;
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _t;
_t = 1;
//cin>>_t;
while (_t--) {
solve();
}
return 0;
}
树分块
P6177 Count on a tree II/【模板】树分块
虚树
P2495 [SDOI2011] 消耗战
珂朵莉树
CF896C Willem, Chtholly and Seniorious
你可能感兴趣的:(ACM模板,数据结构,算法,c++)
机器学习与深度学习间关系与区别
ℒℴѵℯ心·动ꦿ໊ོ꫞
人工智能 学习 深度学习 python
一、机器学习概述定义机器学习(MachineLearning,ML)是一种通过数据驱动的方法,利用统计学和计算算法来训练模型,使计算机能够从数据中学习并自动进行预测或决策。机器学习通过分析大量数据样本,识别其中的模式和规律,从而对新的数据进行判断。其核心在于通过训练过程,让模型不断优化和提升其预测准确性。主要类型1.监督学习(SupervisedLearning)监督学习是指在训练数据集中包含输入
c++ 的iostream 和 c++的stdio的区别和联系
黄卷青灯77
c++ 算法 开发语言 iostream stdio
在C++中,iostream和C语言的stdio.h都是用于处理输入输出的库,但它们在设计、用法和功能上有许多不同。以下是两者的区别和联系:区别1.编程风格iostream(C++风格):C++标准库中的输入输出流类库,支持面向对象的输入输出操作。典型用法是cin(输入)和cout(输出),使用>操作符来处理数据。更加类型安全,支持用户自定义类型的输入输出。#includeintmain(){in
Goolge earth studio 进阶4——路径修改与平滑
陟彼高冈yu
Google earth studio 进阶教程 旅游
如果我们希望在大约中途时获得更多的城市鸟瞰视角。可以将相机拖动到这里并创建一个新的关键帧。camera_target_clip_7EarthStudio会自动平滑我们的路径,所以当我们通过这个关键帧时,不是一个生硬的角度,而是一个平滑的曲线。camera_target_clip_8路径上有贝塞尔控制手柄,允许我们调整路径的形状。右键单击,我们可以选择“平滑路径”,这是默认的自动平滑算法,或者我们可
基于社交网络算法优化的二维最大熵图像分割
智能算法研学社(Jack旭)
智能优化算法应用 图像分割 算法 php 开发语言
智能优化算法应用:基于社交网络优化的二维最大熵图像阈值分割-附代码文章目录智能优化算法应用:基于社交网络优化的二维最大熵图像阈值分割-附代码1.前言2.二维最大熵阈值分割原理3.基于社交网络优化的多阈值分割4.算法结果:5.参考文献:6.Matlab代码摘要:本文介绍基于最大熵的图像分割,并且应用社交网络算法进行阈值寻优。1.前言阅读此文章前,请阅读《图像分割:直方图区域划分及信息统计介绍》htt
数组去重
好奇的猫猫猫
整理自js中基础数据结构数组去重问题思考?如何去除数组中重复的项例如数组:[1,3,4,3,5]我们在做去重的时候,一开始想到的肯定是,逐个比较,外面一层循环,内层后一个与前一个一比较,如果是久不将当前这一项放进新的数组,挨个比较完之后返回一个新的去过重复的数组不好的实践方式上述方法效率极低,代码量还多,思考?有没有更好的方法这时候不禁一想当然有了!!!hashtable啊,通过对象的hash办法
121. 买卖股票的最佳时机
薄荷糖的味道_fb40
给定一个数组,它的第i个元素是一支给定股票第i天的价格。如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。注意你不能在买入股票前卖出股票。示例1:输入:[7,1,5,3,6,4]输出:5解释:在第2天(股票价格=1)的时候买入,在第5天(股票价格=6)的时候卖出,最大利润=6-1=5。注意利润不能是7-1=6,因为卖出价格需要大于买入价格。示例2:输入:
【JS】执行时长(100分) |思路参考+代码解析(C++)
l939035548
JS 算法 数据结构 c++
题目为了充分发挥GPU算力,需要尽可能多的将任务交给GPU执行,现在有一个任务数组,数组元素表示在这1秒内新增的任务个数且每秒都有新增任务。假设GPU最多一次执行n个任务,一次执行耗时1秒,在保证GPU不空闲情况下,最少需要多长时间执行完成。题目输入第一个参数为GPU一次最多执行的任务个数,取值范围[1,10000]第二个参数为任务数组长度,取值范围[1,10000]第三个参数为任务数组,数字范围
每日算法&面试题,大厂特训二十八天——第二十天(树)
肥学
⚡算法题⚡面试题每日精进 java 算法 数据结构
目录标题导读算法特训二十八天面试题点击直接资料领取导读肥友们为了更好的去帮助新同学适应算法和面试题,最近我们开始进行专项突击一步一步来。上一期我们完成了动态规划二十一天现在我们进行下一项对各类算法进行二十八天的一个小总结。还在等什么快来一起肥学进行二十八天挑战吧!!特别介绍小白练手专栏,适合刚入手的新人欢迎订阅编程小白进阶python有趣练手项目里面包括了像《机器人尬聊》《恶搞程序》这样的有趣文章
回溯算法-重新安排行程
chirou_
算法 数据结构 图论 c++ 图搜索
leetcode332.重新安排行程这题我还没自己ac过,只能现在凭着刚学完的热乎劲把我对题解的理解记下来。本题我认为对数据结构的考察比较多,用什么数据结构去存数据,去读取数据,都是很重要的。classSolution{private:unordered_map>targets;boolbacktracking(intticketNum,vector&result){//1.确定参数和返回值//2
Redis系列:Geo 类型赋能亿级地图位置计算
Ly768768
redis bootstrap 数据库
1前言我们在篇深刻理解高性能Redis的本质的时候就介绍过Redis的几种基本数据结构,它是基于不同业务场景而设计的:动态字符串(REDIS_STRING):整数(REDIS_ENCODING_INT)、字符串(REDIS_ENCODING_RAW)双端列表(REDIS_ENCODING_LINKEDLIST)压缩列表(REDIS_ENCODING_ZIPLIST)跳跃表(REDIS_ENCODI
基于CODESYS的多轴运动控制程序框架:逻辑与运动控制分离,快速开发灵活操作
GPJnCrbBdl
python 开发语言
基于codesys开发的多轴运动控制程序框架,将逻辑与运动控制分离,将单轴控制封装成功能块,对该功能块的操作包含了所有的单轴控制(归零、点动、相对定位、绝对定位、设置当前位置、伺服模式切换等等)。程序框架由主程序按照状态调用分归零模式、手动模式、自动模式、故障模式,程序状态的跳转都已完成,只需要根据不同的工艺要求完成所需的动作即可。变量的声明、地址的规划都严格按照C++的标准定义,能帮助开发者快速
C++ | Leetcode C++题解之第409题最长回文串
Ddddddd_158
经验分享 C++ Leetcode 题解
题目:题解:classSolution{public:intlongestPalindrome(strings){unordered_mapcount;intans=0;for(charc:s)++count[c];for(autop:count){intv=p.second;ans+=v/2*2;if(v%2==1andans%2==0)++ans;}returnans;}};
C++菜鸟教程 - 从入门到精通 第二节
DreamByte
c++
一.上节课的补充(数据类型)1.前言继上节课,我们主要讲解了输入,输出和运算符,我们现在来补充一下数据类型的知识上节课遗漏了这个知识点,非常的抱歉顺便说一下,博主要上高中了,更新会慢,2-4周更新一次对了,正好赶上中秋节,小编跟大家说一句:中秋节快乐!2.int类型上节课,我们其实只用了int类型int类型,是整数类型,它们存贮的是整数,不能存小数(浮点数)定义变量的方式很简单inta;//定义一
Faiss:高效相似性搜索与聚类的利器
网络·魚
大数据 faiss
Faiss是一个针对大规模向量集合的相似性搜索库,由FacebookAIResearch开发。它提供了一系列高效的算法和数据结构,用于加速向量之间的相似性搜索,特别是在大规模数据集上。本文将介绍Faiss的原理、核心功能以及如何在实际项目中使用它。Faiss原理:近似最近邻搜索:Faiss的核心功能之一是近似最近邻搜索,它能够高效地在大规模数据集中找到与给定查询向量最相似的向量。这种搜索是近似的,
数据结构之哈希表
X同学的开始
数据结构 数据结构 散列表
哈希表(散列表)出现的原因在顺序表中查找时,需要从表头开始,依次遍历比较a[i]与key的值是否相等,直到相等才返回索引i;在有序表中查找时,我们经常使用的是二分查找,通过比较key与a[i]的大小来折半查找,直到相等时才返回索引i。最终通过索引找到我们要找的元素。但是,这两种方法的效率都依赖于查找中比较的次数。我们有一种想法,能不能不经过比较,而是直接通过关键字key一次得到所要的结果呢?这时,
insert into select 主键自增_mybatis拦截器实现主键自动生成
weixin_39521651
insert into select 主键自增 mybatis delete返回值 mybatis insert返回主键 mybatis insert返回对象 mybatis plus insert返回主键 mybatis plus 插入生成id
前言前阵子和朋友聊天,他说他们项目有个需求,要实现主键自动生成,不想每次新增的时候,都手动设置主键。于是我就问他,那你们数据库表设置主键自动递增不就得了。他的回答是他们项目目前的id都是采用雪花算法来生成,因此为了项目稳定性,不会切换id的生成方式。朋友问我有没有什么实现思路,他们公司的orm框架是mybatis,我就建议他说,不然让你老大把mybatis切换成mybatis-plus。mybat
k均值聚类算法考试例题_k均值算法(k均值聚类算法计算题)
寻找你83497
k均值聚类算法考试例题
?算法:第一步:选K个初始聚类中心,z1(1),z2(1),…,zK(1),其中括号内的序号为寻找聚类中心的迭代运算的次序号。聚类中心的向量值可任意设定,例如可选开始的K个.k均值聚类:---------一种硬聚类算法,隶属度只有两个取值0或1,提出的基本根据是“类内误差平方和最小化”准则;模糊的c均值聚类算法:--------一种模糊聚类算法,是.K均值聚类算法是先随机选取K个对象作为初始的聚类
Python开发常用的三方模块如下:
换个网名有点难
python 开发语言
Python是一门功能强大的编程语言,拥有丰富的第三方库,这些库为开发者提供了极大的便利。以下是100个常用的Python库,涵盖了多个领域:1、NumPy,用于科学计算的基础库。2、Pandas,提供数据结构和数据分析工具。3、Matplotlib,一个绘图库。4、Scikit-learn,机器学习库。5、SciPy,用于数学、科学和工程的库。6、TensorFlow,由Google开发的开源机
Python实现简单的机器学习算法
master_chenchengg
python python 办公效率 python开发 IT
Python实现简单的机器学习算法开篇:初探机器学习的奇妙之旅搭建环境:一切从安装开始必备工具箱第一步:安装Anaconda和JupyterNotebook小贴士:如何配置Python环境变量算法初体验:从零开始的Python机器学习线性回归:让数据说话数据准备:从哪里找数据编码实战:Python实现线性回归模型评估:如何判断模型好坏逻辑回归:从分类开始理论入门:什么是逻辑回归代码实现:使用skl
推荐算法_隐语义-梯度下降
_feivirus_
算法 机器学习和数学 推荐算法 机器学习 隐语义
importnumpyasnp1.模型实现"""inputrate_matrix:M行N列的评分矩阵,值为P*Q.P:初始化用户特征矩阵M*K.Q:初始化物品特征矩阵K*N.latent_feature_cnt:隐特征的向量个数max_iteration:最大迭代次数alpha:步长lamda:正则化系数output分解之后的P和Q"""defLFM_grad_desc(rate_matrix,l
K近邻算法_分类鸢尾花数据集
_feivirus_
算法 机器学习和数学 分类 机器学习 K近邻
importnumpyasnpimportpandasaspdfromsklearn.datasetsimportload_irisfromsklearn.model_selectionimporttrain_test_splitfromsklearn.metricsimportaccuracy_score1.数据预处理iris=load_iris()df=pd.DataFrame(data=ir
Java面试题精选:消息队列(二)
芒果不是芒
Java面试题精选 java kafka
一、Kafka的特性1.消息持久化:消息存储在磁盘,所以消息不会丢失2.高吞吐量:可以轻松实现单机百万级别的并发3.扩展性:扩展性强,还是动态扩展4.多客户端支持:支持多种语言(Java、C、C++、GO、)5.KafkaStreams(一个天生的流处理):在双十一或者销售大屏就会用到这种流处理。使用KafkaStreams可以快速的把销售额统计出来6.安全机制:Kafka进行生产或者消费的时候会
数据结构 | 栈和队列
TT-Kun
数据结构与算法 数据结构 栈 队列 C语言
文章目录栈和队列1.栈:后进先出(LIFO)的数据结构1.1概念与结构1.2栈的实现2.队列:先进先出(FIFO)的数据结构2.1概念与结构2.2队列的实现3.栈和队列算法题3.1有效的括号3.2用队列实现栈3.3用栈实现队列3.4设计循环队列结论栈和队列在计算机科学中,栈和队列是两种基本且重要的数据结构,它们在处理数据存储和访问顺序方面有着独特的规则和应用。本文将详细介绍栈和队列的概念、结构、实
[Python] 数据结构 详解及代码
AIAdvocate
算法 python 数据结构 链表
今日内容大纲介绍数据结构介绍列表链表1.数据结构和算法简介程序大白话翻译,程序=数据结构+算法数据结构指的是存储,组织数据的方式.算法指的是为了解决实际业务问题而思考思路和方法,就叫:算法.2.算法的5大特性介绍算法具有独立性算法是解决问题的思路和方式,最重要的是思维,而不是语言,其(算法)可以通过多种语言进行演绎.5大特性有输入,需要传入1或者多个参数有输出,需要返回1个或者多个结果有穷性,执行
4.C_数据结构_队列
荣世蓥
数据结构 数据结构
概述什么是队列:队列是限定在两端进行插入操作和删除操作的线性表。具有先入先出(FIFO)的特点相关名词:队尾:写入数据的一段队头:读取数据的一段空队:队列中没有数据,队头指针=队尾指针满队:队列中存满了数据,队尾指针+1=队头指针循环队列1、基本内容循环队列是以数组形式构成的队列数据结构。循环队列的结构体如下:typedefintdata_t;//队列数据类型#defineN64//队列容量typ
Python算法L5:贪心算法
小熊同学哦
Python算法 算法 python 贪心算法
Python贪心算法简介目录Python贪心算法简介贪心算法的基本步骤贪心算法的适用场景经典贪心算法问题1.**零钱兑换问题**2.**区间调度问题**3.**背包问题**贪心算法的优缺点优点:缺点:结语贪心算法(GreedyAlgorithm)是一种在每一步选择中都采取当前最优或最优解的算法。它的核心思想是,在保证每一步局部最优的情况下,希望通过贪心选择达到全局最优解。虽然贪心算法并不总能得到全
C++ lambda闭包消除类成员变量
barbyQAQ
c++ c++ java 算法
原文链接:https://blog.csdn.net/qq_51470638/article/details/142151502一、背景在面向对象编程时,常常要添加类成员变量。然而类成员一旦多了之后,也会带来干扰。拿到一个类,一看成员变量好几十个,就问你怕不怕?二、解决思路可以借助函数式编程思想,来消除一些不必要的类成员变量。三、实例举个例子:classClassA{public:...intfu
2021 CCF 非专业级别软件能力认证第一轮(CSP-J1)入门级C++语言试题 (第三大题:完善程序 代码)
mmz1207
c++ csp
最近有一段时间没更新了,在准备CSP考试,请大家见谅。(1)有n个人围成一个圈,依次标号0到n-1。从0号开始,依次0,1,0,1...交替报数,报到一的人离开,直至圈中剩最后一个人。求最后剩下的人的编号。#includeusingnamespacestd;intf[1000010];intmain(){intn;cin>>n;inti=0,cnt=0,p=0;while(cnt#includeu
《 C++ 修炼全景指南:九 》打破编程瓶颈!掌握二叉搜索树的高效实现与技巧
Lenyiin
C++ 修炼全景指南 技术指南 c++ 算法 stl
摘要本文详细探讨了二叉搜索树(BinarySearchTree,BST)的核心概念和技术细节,包括插入、查找、删除、遍历等基本操作,并结合实际代码演示了如何实现这些功能。文章深入分析了二叉搜索树的性能优势及其时间复杂度,同时介绍了前驱、后继的查找方法等高级功能。通过自定义实现的二叉搜索树类,读者能够掌握其实际应用,此外,文章还建议进一步扩展为平衡树(如AVL树、红黑树)以优化极端情况下的性能退化。
20个新手学习c++必会的程序 输出*三角形、杨辉三角等(附代码)
X_StarX
c++ 学习 算法 大学生 开发语言 数据结构
示例1:HelloWorld#includeusingnamespacestd;intmain(){coutusingnamespacestd;intmain(){inta=5;intb=10;intsum=a+b;coutusingnamespacestd;intfactorial(intn){if(nusingnamespacestd;voidprintFibonacci(intn){intt
Spring4.1新特性——综述
jinnianshilongnian
spring 4.1
目录
Spring4.1新特性——综述
Spring4.1新特性——Spring核心部分及其他
Spring4.1新特性——Spring缓存框架增强
Spring4.1新特性——异步调用和事件机制的异常处理
Spring4.1新特性——数据库集成测试脚本初始化
Spring4.1新特性——Spring MVC增强
Spring4.1新特性——页面自动化测试框架Spring MVC T
Schema与数据类型优化
annan211
数据结构 mysql
目前商城的数据库设计真是一塌糊涂,表堆叠让人不忍直视,无脑的架构师,说了也不听。
在数据库设计之初,就应该仔细揣摩可能会有哪些查询,有没有更复杂的查询,而不是仅仅突出
很表面的业务需求,这样做会让你的数据库性能成倍提高,当然,丑陋的架构师是不会这样去考虑问题的。
选择优化的数据类型
1 更小的通常更好
更小的数据类型通常更快,因为他们占用更少的磁盘、内存和cpu缓存,
第一节 HTML概要学习
chenke
html Web css
第一节 HTML概要学习
1. 什么是HTML
HTML是英文Hyper Text Mark-up Language(超文本标记语言)的缩写,它规定了自己的语法规则,用来表示比“文本”更丰富的意义,比如图片,表格,链接等。浏览器(IE,FireFox等)软件知道HTML语言的语法,可以用来查看HTML文档。目前互联网上的绝大部分网页都是使用HTML编写的。
打开记事本 输入一下内
MyEclipse里部分习惯的更改
Array_06
eclipse
继续补充中----------------------
1.更改自己合适快捷键windows-->prefences-->java-->editor-->Content Assist-->
Activation triggers for java的右侧“.”就可以改变常用的快捷键
选中 Text
近一个月的面试总结
cugfy
面试
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/46753275
前言
打算换个工作,近一个月面试了不少的公司,下面将一些面试经验和思考分享给大家。另外校招也快要开始了,为在校的学生提供一些经验供参考,希望都能找到满意的工作。 
HTML5一个小迷宫游戏
357029540
html5
通过《HTML5游戏开发》摘抄了一个小迷宫游戏,感觉还不错,可以画画,写字,把摘抄的代码放上来分享下,喜欢的同学可以拿来玩玩!
<html>
<head>
<title>创建运行迷宫</title>
<script type="text/javascript"
10步教你上传githib数据
张亚雄
git
官方的教学还有其他博客里教的都是给懂的人说得,对已我们这样对我大菜鸟只能这么来锻炼,下面先不玩什么深奥的,先暂时用着10步干净利索。等玩顺溜了再用其他的方法。
操作过程(查看本目录下有哪些文件NO.1)ls
(跳转到子目录NO.2)cd+空格+目录
(继续NO.3)ls
(匹配到子目录NO.4)cd+ 目录首写字母+tab键+(首写字母“直到你所用文件根就不再按TAB键了”)
(查看文件
MongoDB常用操作命令大全
adminjun
mongodb 操作命令
成功启动MongoDB后,再打开一个命令行窗口输入mongo,就可以进行数据库的一些操作。输入help可以看到基本操作命令,只是MongoDB没有创建数据库的命令,但有类似的命令 如:如果你想创建一个“myTest”的数据库,先运行use myTest命令,之后就做一些操作(如:db.createCollection('user')),这样就可以创建一个名叫“myTest”的数据库。
一
bat调用jar包并传入多个参数
aijuans
下面的主程序是通过eclipse写的:
1.在Main函数接收bat文件传递的参数(String[] args)
如: String ip =args[0]; String user=args[1]; &nbs
Java中对类的主动引用和被动引用
ayaoxinchao
java 主动引用 对类的引用 被动引用 类初始化
在Java代码中,有些类看上去初始化了,但其实没有。例如定义一定长度某一类型的数组,看上去数组中所有的元素已经被初始化,实际上一个都没有。对于类的初始化,虚拟机规范严格规定了只有对该类进行主动引用时,才会触发。而除此之外的所有引用方式称之为对类的被动引用,不会触发类的初始化。虚拟机规范严格地规定了有且仅有四种情况是对类的主动引用,即必须立即对类进行初始化。四种情况如下:1.遇到ne
导出数据库 提示 outfile disabled
BigBird2012
mysql
在windows控制台下,登陆mysql,备份数据库:
mysql>mysqldump -u root -p test test > D:\test.sql
使用命令 mysqldump 格式如下: mysqldump -u root -p *** DBNAME > E:\\test.sql。
注意:执行该命令的时候不要进入mysql的控制台再使用,这样会报
Javascript 中的 && 和 ||
bijian1013
JavaScript && ||
准备两个对象用于下面的讨论
var alice = {
name: "alice",
toString: function () {
return this.name;
}
}
var smith = {
name: "smith",
[Zookeeper学习笔记之四]Zookeeper Client Library会话重建
bit1129
zookeeper
为了说明问题,先来看个简单的示例代码:
package com.tom.zookeeper.book;
import com.tom.Host;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.Wat
【Scala十一】Scala核心五:case模式匹配
bit1129
scala
package spark.examples.scala.grammars.caseclasses
object CaseClass_Test00 {
def simpleMatch(arg: Any) = arg match {
case v: Int => "This is an Int"
case v: (Int, String)
运维的一些面试题
yuxianhua
linux
1、Linux挂载Winodws共享文件夹
mount -t cifs //1.1.1.254/ok /var/tmp/share/ -o username=administrator,password=yourpass
或
mount -t cifs -o username=xxx,password=xxxx //1.1.1.1/a /win
Java lang包-Boolean
BrokenDreams
boolean
Boolean类是Java中基本类型boolean的包装类。这个类比较简单,直接看源代码吧。
public final class Boolean implements java.io.Serializable,
读《研磨设计模式》-代码笔记-命令模式-Command
bylijinnan
java 设计模式
声明: 本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* GOF 在《设计模式》一书中阐述命令模式的意图:“将一个请求封装
matlab下GPU编程笔记
cherishLC
matlab
不多说,直接上代码
gpuDevice % 查看系统中的gpu,,其中的DeviceSupported会给出matlab支持的GPU个数。
g=gpuDevice(1); %会清空 GPU 1中的所有数据,,将GPU1 设为当前GPU
reset(g) %也可以清空GPU中数据。
a=1;
a=gpuArray(a); %将a从CPU移到GPU中
onGP
SVN安装过程
crabdave
SVN
SVN安装过程
subversion-1.6.12
./configure --prefix=/usr/local/subversion --with-apxs=/usr/local/apache2/bin/apxs --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr --with-openssl=/
sql 行列转换
daizj
sql 行列转换 行转列 列转行
行转列的思想是通过case when 来实现
列转行的思想是通过union all 来实现
下面具体例子:
假设有张学生成绩表(tb)如下:
Name Subject Result
张三 语文 74
张三 数学 83
张三 物理 93
李四 语文 74
李四 数学 84
李四 物理 94
*/
/*
想变成
姓名 &
MySQL--主从配置
dcj3sjt126com
mysql
linux下的mysql主从配置: 说明:由于MySQL不同版本之间的(二进制日志)binlog格式可能会不一样,因此最好的搭配组合是Master的MySQL版本和Slave的版本相同或者更低, Master的版本肯定不能高于Slave版本。(版本向下兼容)
mysql1 : 192.168.100.1 //master mysq
关于yii 数据库添加新字段之后model类的修改
dcj3sjt126com
Model
rules:
array('新字段','safe','on'=>'search')
1、array('新字段', 'safe')//这个如果是要用户输入的话,要加一下,
2、array('新字段', 'numerical'),//如果是数字的话
3、array('新字段', 'length', 'max'=>100),//如果是文本
1、2、3适当的最少要加一条,新字段才会被
sublime text3 中文乱码解决
dyy_gusi
Sublime Text
sublime text3中文乱码解决
原因:缺少转换为UTF-8的插件
目的:安装ConvertToUTF8插件包
第一步:安装能自动安装插件的插件,百度“Codecs33”,然后按照步骤可以得到以下一段代码:
import urllib.request,os,hashlib; h = 'eb2297e1a458f27d836c04bb0cbaf282' + 'd0e7a30980927
概念了解:CGI,FastCGI,PHP-CGI与PHP-FPM
geeksun
PHP
CGI
CGI全称是“公共网关接口”(Common Gateway Interface),HTTP服务器与你的或其它机器上的程序进行“交谈”的一种工具,其程序须运行在网络服务器上。
CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。如php,perl,tcl等。 FastCGI
FastCGI像是一个常驻(long-live)型的CGI,它可以一直执行着,只要激活后,不
Git push 报错 "error: failed to push some refs to " 解决
hongtoushizi
git
Git push 报错 "error: failed to push some refs to " .
此问题出现的原因是:由于远程仓库中代码版本与本地不一致冲突导致的。
由于我在第一次git pull --rebase 代码后,准备push的时候,有别人往线上又提交了代码。所以出现此问题。
解决方案:
1: git pull
2:
第四章 Lua模块开发
jinnianshilongnian
nginx lua
在实际开发中,不可能把所有代码写到一个大而全的lua文件中,需要进行分模块开发;而且模块化是高性能Lua应用的关键。使用require第一次导入模块后,所有Nginx 进程全局共享模块的数据和代码,每个Worker进程需要时会得到此模块的一个副本(Copy-On-Write),即模块可以认为是每Worker进程共享而不是每Nginx Server共享;另外注意之前我们使用init_by_lua中初
java.lang.reflect.Proxy
liyonghui160com
1.简介
Proxy 提供用于创建动态代理类和实例的静态方法
(1)动态代理类的属性
代理类是公共的、最终的,而不是抽象的
未指定代理类的非限定名称。但是,以字符串 "$Proxy" 开头的类名空间应该为代理类保留
代理类扩展 java.lang.reflect.Proxy
代理类会按同一顺序准确地实现其创建时指定的接口
Java中getResourceAsStream的用法
pda158
java
1.Java中的getResourceAsStream有以下几种: 1. Class.getResourceAsStream(String path) : path 不以’/'开头时默认是从此类所在的包下取资源,以’/'开头则是从ClassPath根下获取。其只是通过path构造一个绝对路径,最终还是由ClassLoader获取资源。 2. Class.getClassLoader.get
spring 包官方下载地址(非maven)
sinnk
spring
SPRING官方网站改版后,建议都是通过 Maven和Gradle下载,对不使用Maven和Gradle开发项目的,下载就非常麻烦,下给出Spring Framework jar官方直接下载路径:
http://repo.springsource.org/libs-release-local/org/springframework/spring/
s
Oracle学习笔记(7) 开发PLSQL子程序和包
vipbooks
oracle sql 编程
哈哈,清明节放假回去了一下,真是太好了,回家的感觉真好啊!现在又开始出差之旅了,又好久没有来了,今天继续Oracle的学习!
这是第七章的学习笔记,学习完第六章的动态SQL之后,开始要学习子程序和包的使用了……,希望大家能多给俺一些支持啊!
编程时使用的工具是PLSQL