> _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++)
【数据结构】考点 二十四:快速排序算法
超越超
数据结构考试【临时抱佛脚】 结构算法 排序算法 数据结构 算法 快速排序
【考试临时抱佛脚】系列文章针对于、、的考生打造。无论你是、还是这个专栏都适合你,Let’sgo!一、方法快速排序是一种分治算法,它将数据分为两个子集,其中一个子集的所有数据都比另一个子集的所有数据要小,然后递归地对这两个子集进行快速排序操作。需先选择一个基准数,然后再将小的放左,大的放右,递归进行排序。每个子序列用插入排序解决排序问题。二、考察形式11、问题取键值55为基准,执行一趟快速排序后可能
【数据结构】清华出版社-刘小晶、朱蓉《数据结构渐进实践指导》第一章(个人手打版)
shixiexunnie
立志从0到c++全栈志 数据结构 算法 c++
文章目录1_1_SqList.cpp1_1_LinkList.cpp1_1_SqList.cpp#include#include#definesql_size100//线性表初始分配空间的容量#definekuo10//线性表扩展空间的量#defineERROR0#defineOK1#defineOVERFLOW-2typedefintElemType;//数据元素的抽象数据类型,一般为intty
微服务架构中的负载均衡与服务注册中心(Nacos)
ღ᭄ꦿ࿐Never say never꧂
微服务 架构 微服务 负载均衡 spring cloud spring boot 后端 java
1.负载均衡:解决实际业务问题1.1业务场景思考想象一个电子商务平台的微服务架构。我们有一个订单服务和多个用户服务实例。当订单服务需要调用用户服务时,它如何选择具体调用哪一台用户服务器?这就是负载均衡要解决的核心问题。1.2常用负载均衡算法及其业务影响1.2.1轮询(RoundRobin)原理:请求依次分配给每个服务器。业务影响:优点:实现简单,在服务器性能相近的情况下能达到较好的负载平衡。缺点:
Redis 集群模式的工作原理能说一下么?
小新杂谈社
缓存 后端面试 redis 数据库 缓存 分布式
面试题Redis集群模式的工作原理能说一下么?在集群模式下,Redis的key是如何寻址的?分布式寻址都有哪些算法?了解一致性hash算法吗?面试官心理分析在前几年,Redis如果要搞几个节点,每个节点存储一部分的数据,得借助一些中间件来实现,比如说有codis,或者twemproxy,都有。有一些Redis中间件,你读写Redis中间件,Redis中间件负责将你的数据分布式存储在多台机器上的Re
二十redis之gossip协议
我爱看明朝
后端
二十redis之gossip协议gossip协议是p2p方式的通信协议。通过节点之间不断交换信息,一段时间后所有节点都会知道整个集群完整的信息。gossip算法,意思是八卦算法,在办公室中只要一个人八卦一下,在有限的时间内,办公室内的所有人都会知道八卦消息。算法过程:集群中的一个节点广播自身信息,部分节点收到了信息,这些节点再继续在集群中传播这个节点的信息,一段时间后整个集群中都有了这个节点的信息
MATLAB算法实战应用案例精讲-【目标检测】机器视觉-工业相机(补充篇)
林聪木
数码相机 matlab 算法
目录知识储备光学系统设计全过程算法原理工业相机基本参数以及选型工业相机基本参数:如何选择合适的工业相机:分辨率分辨率的定义与“检测/测量精度”的区别分辨率与相机的匹配相机关键参数设置工业相机的曝光、曝光时间、快门、增益什么是曝光?什么是快门影响曝光的因素工业相机-坐标系和机械手坐标系的标定工业相机-缺陷检测一、相机的选择(1)工业数字相机的分类:(2)相机的主要参数(3)工业数字摄像机主要接口类型
LeetCode解决方案集:编程与面试技能提升
徐子贡
本文还有配套的精品资源,点击获取简介:LeetCode是一个编程训练平台,提供了大量编程题目,用于提升开发者的算法技能和面试准备。本文将探讨名为"some-leetcode-solutions"的开源项目,其中包括LeetCode问题的多种编程语言解决方案。这些解决方案由社区成员贡献,可用于学习不同思路和比较语言实现。开源项目遵循开源协议,允许自由使用和修改代码,鼓励知识共享。本文还强调了学习算法
C#——垃圾回收(GC)
面向大象编程
C# c# 开发语言 面向对象编程
文章目录前言一、垃圾回收是什么二、好处三、GC过程1.GC条件2.GC步骤3.Mark-Compact标记压缩算法4.Generational分代算法5.FinalizationQueue和FreachableQueue四、托管和非托管资源1.托管资源2.非托管资源五、GC注意事项参考前言C#的垃圾回收网上有很多博客进行讲解,这里摘录一部分较好的讲解,同时建议直接使用微软官方文档,万变不离其宗一、
Leetcode 3459. Length of Longest V-Shaped Diagonal Segment
Espresso Macchiato
leetcode笔记 leetcode 3459 leetcode hard leetcode周赛437 动态规划 剪枝
Leetcode3459.LengthofLongestV-ShapedDiagonalSegment1.解题思路2.代码实现题目链接:3459.LengthofLongestV-ShapedDiagonalSegment1.解题思路这一题我的思路上就是一个动态规划加上剪枝的思路。首先,不难给出一个动态规划算法来考察每一个位置作为起始点时其所能获得的最大V字路径长度,但是,贸然地动态规划会出现超时
Java每日精进·45天挑战·Day14
云朵大王
开发语言 算法
第一部分:逆波兰表达式求值在编程中,逆波兰表达式(ReversePolishNotation,RPN)是一种后缀表达式,它的特点是将运算符写在操作数的后面。这种表达式形式在处理算术运算时具有许多优点,尤其是它非常适合使用栈数据结构来进行求值。今天,我们将通过Java代码来实现一个逆波兰表达式的求值器。逆波兰表达式的优点无括号表达式无歧义:在逆波兰表达式中,由于运算符始终写在操作数的后面,因此即使去
【C++】双指针算法专题
啊QQQQQ
c++ 数据结构 开发语言
目录前言对撞指针快慢指针习题练习1.移动零.-力扣(LeetCode)算法思路算法流程代码实现2.复写零.-力扣(LeetCode)算法思路算法流程代码实现3.快乐数.-力扣(LeetCode)算法思路算法流程代码实现4.盛水最多的容器.-力扣(LeetCode)算法思路代码实现5.有效三角形的个数.-力扣(LeetCode)算法思路代码实现6.和为S的两个数.-力扣(LeetCode)算法思路代
C/C++程序在不同环境中迁移时的注意事项
coolhuhu~
cpp 工程问题 linux c++ linux 工程实践
问题在你的开发环境中,编译、链接、运行测试都没问题,迁移到其他机器上运行程序时,程序运行不起来或运行异常。场景一开发环境的机器CPU为ARM架构,而测试环境的机器CPU为x86架构。场景二测试环境中缺乏程序依赖的库。体现在没有把开发环境中编译时所依赖的相关库迁移到测试环境中。场景三测试环境中程序运行时,所依赖库的版本不一致。一种场景是,程序在开发环境中编译、链接依赖libstdc++.so.6.0
golang 调用 c++ (cgo)
LRZ0001
Go c++ golang
文章目录目录结构各文件对应的代码library.hpplibrary.cpplibrary-bridge.hlibrary-bridge.cppmain.go方式一:调用静态链接库编译静态链接库运行方式二:调用动态链接库生成动态链接库运行注意:调用动态库会有加载不到的情况参考文章目录结构[root@localhostexample03]#tree.├──library│├──library-bri
golang调用c库函数
wx_kingstone
cpp golang c++ golang go c语言 cgo
golang调用c库函数c语言相关代码golang相关代码golang编译本文章介绍了golang如何调用c语言库函数。如果想调用c++库函数,建议在c++上再封一层c语言代码,编译成c语言动态库,再被golang调用。c语言相关代码cc文件、so编译省略c头文件,mytest.h#ifndef__MYTEST_H_#define__MYTEST_H_#ifdef__cplusplusextern
数据结构--顺序表
EnigmaCoder
数据结构 数据结构 算法
顺序表1.概念和结构2.分类2.1静态顺序表2.2动态顺序表3.动态顺序表代码实现3.1顺序表的定义3.2顺序表初始化3.3顺序表的销毁3.4顺序表的插入3.5顺序表的删除3.6顺序表在指定位置之前插入/删除数据3.7顺序表的查找4.总结1.概念和结构概念:顺序表是线性表1的一种存储方式,它是用一组地址连续的存储单元依次存储线性表中的数据元素。简单来说,就像是把一系列的数据一个挨着一个地存放在一块
智能硬件定位技术发展趋势
2401_88540551
智能硬件 智能手表 物联网 宠物 智慧城市 uni-app 微信小程序
在科技飞速进步的当下,智能硬件定位技术作为众多领域的关键支撑,正沿着多元且极具创新性的路径蓬勃发展,持续重塑我们的生活与工作方式。一、精度提升的极致追求当前,智能硬件定位精度虽已满足诸多日常应用,但未来发展仍聚焦高精度突破。在自动驾驶领域,厘米级甚至毫米级定位精度至关重要。科研人员正致力于融合多种定位技术,如卫星定位、惯性导航、视觉识别与高精度地图匹配。通过复杂算法协同运作,车辆在复杂路况下能精准
【自学笔记】机器学习基础知识点总览-持续更新
Long_poem
笔记 机器学习 人工智能
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录机器学习重点知识点总览一、机器学习基础概念二、机器学习理论基础三、机器学习算法1.监督学习2.无监督学习3.强化学习四、机器学习处理流程五、机器学习常见问题与解决方法六、机器学习应用领域总结机器学习重点知识点总览一、机器学习基础概念定义:机器学习是一种人工智能技术,通过对数据的学习和分析,让计算机系统自动提高其性能。本质:找到
解锁机器学习核心算法 | 逻辑回归:不是回归的“回归”
紫雾凌寒
AI 炼金厂 机器学习 算法 逻辑回归 深度学习 python scikit-learn matplotlib
引言前面一篇文章我们介绍了机器学习算法中我们最先会接触到的算法——线性回归:机器学习的基石。今天我们继续学习机器学习中的另一个算法模型——逻辑回归(LogisticRegression)。一、逻辑回归:不是回归的“回归”在机器学习的庞大算法体系中,逻辑回归(LogisticRegression)虽然名字中带有“回归”,但却是一位不折不扣的“分类高手”,主要用于解决二分类问题,在众多领域发挥着关键作
JavaScript设计模式 -- 迭代器模式
鎈卟誃筅甡
javascript 设计模式 迭代器模式
在软件开发中,我们经常需要遍历集合、数组、链表、树等数据结构。传统上,这些数据结构往往需要暴露内部实现细节,或者写大量重复的遍历代码。**迭代器模式(IteratorPattern)**提供了一种统一的方式来访问集合内的元素,而不暴露集合的内部表示。通过定义统一的迭代器接口,可以使客户端代码与数据结构实现解耦,从而使系统更易扩展和维护。迭代器模式简介迭代器模式属于行为型设计模式,其主要思想是将遍历
单片机、嵌入式Linux开发大学自学路径
Oriental Son
嵌入式 MCU 单片机 单片机 学习 stm32 mcu linux
笔者所修读的专业为物联网工程,物联网工程是一门新兴的、热门的专业,其所涉及的学科更是又多又杂,既有计算机方向的编程语言(如C、C++、Java、Python等)、数据结构与算法、操作系统、移动端应用开发、机器学习等;软硬结合的方向有数字电路单片机开发、嵌入式Linux开发等;硬件、电路方向有电路分析、数字电路、模拟电路、传感器原理、RFID、FPGA开发等;涉及信号处理的有信号与系统、通信原理等。
蓝桥杯备考:贪心算法之纪念品分组
无敌大饺子 1
贪心算法 算法
P1094[NOIP2007普及组]纪念品分组-洛谷这道题我们的贪心策略就是每次找出最大的和最小的,如果他们加起来不超过我们给的值,就分成一组,如果超过了,就把大的单独成一组,小的待定#include#includetypedeflonglongLL;usingnamespacestd;LLw,n;constintN=3e4+10;LLa[N];intmain(){cin>>w>>n;for(in
有了ChatGPT和deepseek,我们还需要刷力扣吗
Ash Butterfield
人工智能
像ChatGPT这样的AI写手可以帮助我们大幅度提高工作效率,尤其是在代码生成、文档编写等方面。但对于是否需要深入学习基础算法和刷力扣这类问题,还是有一些值得思考的地方。1.AI的局限性深度发问与思考:虽然像ChatGPT这样的AI工具能生成代码,但这些代码生成并不代表你完全不需要理解基础算法。AI可以帮助你自动化一些任务,但它并不能完全替代对问题的深度理解和思考。理解算法的原理和背后的数学知识,
【卡车无人机】遗传算法GA求解卡车联合无人机配送路径规划【含Matlab源码 XYDG001期】
Matlab领域
Matlab路径规划(高阶版) matlab
Matlab领域博客之家博主简介:985研究生,Matlab领域科研开发者;个人主页:Matlab领域代码获取方式:CSDNMatlab领域—代码获取方式座右铭:路漫漫其修远兮,吾将上下而求索。更多Matlab路径规划仿真内容点击①Matlab路径规划(高阶版)②付费专栏Matlab路径规划(进阶版)③付费专栏Matlab路径规划(初级版)⛳️关注CSDNMatlab领域,更多资源等你来!!⛄一、
JavaScript数组-获取数组中的元素
難釋懷
javascript 开发语言 前端
在JavaScript中,数组是一种非常实用的数据结构,它允许我们将多个值存储在一个单独的变量中。无论是数字、字符串还是对象,都可以作为数组的元素。获取数组中的特定元素是操作数组的基础技能之一。本文将详细介绍如何在JavaScript中获取数组中的元素。一、通过索引访问元素基本概念数组中的每个元素都有一个对应的索引,这个索引是从0开始计数的整数。也就是说,第一个元素的索引为0,第二个元素的索引为1
随机梯度下降一定会收敛么?
AndrewHZ
人工智能 深度学习 算法
1.什么是随机梯度下降?随机梯度下降(StochasticGradientDescent,SGD)是一种用于最小化目标函数的迭代优化算法,在机器学习和深度学习领域应用广泛。2.随机梯度下降算法的基本原理1.基于梯度的优化基础该算法是基于梯度的优化算法,用于寻找函数的最优解,通常是最小化损失函数。在机器学习和深度学习中,模型通过调整参数来最小化损失函数,以达到最佳的预测性能。2.迭代更新参数从初始的
CVPR2023 Highlight | ECON:最新单图穿衣人三维重建SOTA算法
3D视觉工坊
3D视觉从入门到精通 算法 SLAM 自动驾驶 3D视觉
作者:宁了个宁|来源:计算机视觉工坊在公众号「3D视觉工坊」后台,回复「原论文」可获取论文pdf。添加微信:dddvisiona,备注:三维重建,拉你入群。文末附行业细分群。图1所示。从彩色图像进行人体数字化。ECON结合了自由形式隐式表示的最佳方面,以及明确的拟人化正则化,以推断高保真度的3D人类,即使是宽松的衣服或具有挑战性的姿势。0.笔者个人体会这篇文章讨论了单图像的穿着人类重建问题。隐式方
从 size_t 到面试官的微笑:我的 C++ 面试历险记
Vitalia
C/C++ # 面试经验 c++ 面试 C
面试复盘之前面试遇到一些很好玩的事情,也学到了很多知识,积累了很多经验。某中厂面试的虚拟表演的第三轮:有一道题我用了经典for循环,大概这样:vectorarr={0,1,2);for(inti=0;i=0;i--){//xxxxxxxx}然后就搞笑了,超时,循环退不出来了。我一拍脑门,size_t是无符号类型诶,赶紧改成int,然后美滋滋。面试官一脸冷漠看完全程,说:我不会C++,也不知道你说的
一文读懂遥感技术在农险服务全流程的应用与价值
珈和info
遥感
农业保险作为分散农业风险、提高农业生产积极性、保障农民收入稳定的重要金融政策工具,其效能直接关系到农业生产的稳定与农村经济的繁荣。然而,传统农业保险业务在信息获取、风险评估等方面的局限性日益凸显。转型之际,科技手段应如何精准地介入到农险业务的发展中来?承保、理赔、风险评估等关键业务环节能否实现从重经验到重数据的转变?已实现商业化应用的遥感技术是否能突破局限,在成本、精度、算法等维度更贴合农险业务的
【C++】类和对象-上
此生只爱蛋
C++ c++
>本系列为初阶C++的内容,如果感兴趣,欢迎订阅>个人主页:[小编的个人主页])小编的个人主页>欢迎大家点赞收藏⭐文章>✌️☝️目录前言类定义访问限定符类域实例化对象对象的大小this指针前言C语言是一门面向过程的语言,在C语言中,我们用结构体来定义复合数据类型的结构。C++在设计中保留了结构体(struct)类型的优点,C++引入了类,类已经包括了结构体类型的所有功能,并且功能更强,更符合面向对
【数据结构与算法】双向链表(添加节点、更新节点、删除节点、打印链表)
Bulut0907
# 数据结构和算法 双向链表 链表 更新节点 删除节点 打印链表
目录1.单向链表的缺点2.双向链表的介绍3.带head头的双向链表实现1.单向链表的缺点前面我们学习了单向链表。虽然有了单向链表,但在解决某些实际问题时,单向链表的执行效率并不高例如,若实际问题中需要频繁地查找某个节点的前驱节点,使用单向链表存储数据显然没有优势因为单向链表的强项是从前往后查找目标元素,不擅长从后往前查找元素。所以就有了双向链表2.双向链表的介绍双向链表是一种复杂类型的链表,它的节
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