> _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++)
卡尔曼滤波算法从理论到实践:在STM32中的嵌入式实现
DOMINICHZL
STM32 算法 stm32 嵌入式硬件
摘要:卡尔曼滤波(KalmanFilter)是传感器数据融合领域的经典算法,在姿态解算、导航定位等嵌入式场景中广泛应用。本文将从公式推导、代码实现、参数调试三个维度深入解析卡尔曼滤波,并给出基于STM32硬件的完整工程案例。一、卡尔曼滤波核心思想1.1什么是卡尔曼滤波?卡尔曼滤波是一种最优递归估计算法,通过融合预测值(系统模型)与观测值(传感器数据),在噪声干扰环境下实现对系统状态的动态估计。其核
递推和递归_一文学会递归递推
HR刀姐
递推和递归
递归算法和递推算法无论是在ACM竞赛还是项目工程上都有着极为广泛的应用,但想要完全掌握两者的思想并不容易,对于刚刚接触编程的人来说更是这样,我在初次接触递归递推时就吃了很多的苦头,除了当时对编程语言不太熟悉之外,最大的原因就是难以理解其中的思想,本文将二者结合代码分别讲解,力求以"理论+实践"的方式使读者明白两种算法。一箭双雕,一文双递。一.递归和递推的区别学习递归递推的一个容易遇到的问题就是混淆
ZooKeeper学习总结(1)——ZooKeeper入门介绍
一杯甜酒
ZooKeeper学习总结 Zookeeper
1.概述Zookeeper是Hadoop的一个子项目,它是分布式系统中的协调系统,可提供的服务主要有:配置服务、名字服务、分布式同步、组服务等。它有如下的一些特点:简单Zookeeper的核心是一个精简的文件系统,它支持一些简单的操作和一些抽象操作,例如,排序和通知。丰富Zookeeper的原语操作是很丰富的,可实现一些协调数据结构和协议。例如,分布式队列、分布式锁和一组同级别节点中的“领导者选举
从零手撕 LLaMa3 项目爆火(图解+代码)
机器学习社区
大模型 深度学习 大模型 算法 人工智能 RAG 多模态大模型 Llama 面试题
节前,我们组织了一场算法岗技术&面试讨论会,邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。针对大模型技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备面试攻略、面试常考点等热门话题进行了深入的讨论。汇总合集《大模型面试宝典》(2024版)发布!一个月前,Meta发布了开源大模型llama3系列,在多个关键基准测试中优于业界SOTA模型,并在代码生成任务上全面领先。此后,开发
从零打造工业级智能二维码识别系统:基于PyQt5与ZXingCpp的实战指南
蜡笔小新星
PyQt5 qt 开发语言 python 图像处理 经验分享 pyqt 扫码读码解码
文章目录第一章:系统全景解析1.1实时识别工作流图解1.2界面布局与功能分区说明1.3代码文件结构树形图第二章:环境搭建与依赖管理2.1必需组件清单2.2虚拟环境配置步骤2.3摄像头硬件检测方法第三章:多线程视频采集3.1VideoThread类设计剖析3.2图像采集核心循环3.3线程安全停止机制3.4信号槽通信实例第四章:图像预处理流水线4.1预处理方法开关实现4.2自适应二值化算法4.3图像格
递推和递归(C语言)
是小万吖
算法 算法 数据结构 c语言
文章目录前言一、递推原理1.递推概念2.递推关系3.递推特点4.递推详例5.解决递推问题的步骤二、递归原理1.递归的概念2.构成递归的条件3.递归的模板4.递归详例三、递推和递归都可实现的算法1.问题描述2.问题分析3.递归实现4.递推实现四、递推和递归的优缺点1.递推的优缺点2.递归的优缺点五、递推和递归的相互转化1.递推转化为递归2.递归转化为递推前言主要探究递推和递归之间的关系提示:以下是本
【OpenCV C++】存图,如何以时间命名,“年月日-时分秒“产生唯一的文件名呢?“年月日-时分秒-毫秒“ 自动检查存储目录,若不存在自动创建存图
R-G-B
OpenCV C++ C/C++ opencv c++ 人工智能
文章目录1生成文件名(格式:"年月日-时分秒"格式)2生成文件名(格式:"年月日-时分秒-毫秒")3多模式存图函数4综合调用实例5注意:默认参数只能在头文件中定义,不能在实现中重复默认参数mode==1→“年月日-时分”→YYYYMMDD-HHMM的文件名;例如:20250310-1647mode==2→"年月日-时分秒-毫秒"→YYYYMMDD-HHMMSS-MMM(适用采集存储帧率搞得图片,增
C++:const和constexpr两个关键字
壹十壹
C++ c++
在C++中,constexpr和const是两个关键字,用于定义常量,但它们有不同的语义和用途。以下是它们的详细对比和示例:1.const含义:表示变量是只读的,其值在程序运行期间不能被修改。初始化:可以在运行时(run-time)进行初始化。用法:通常用于修饰变量、函数参数或返回值。不能保证变量在编译期求值。示例constintx=10;//编译时常量inty=20;constintz=y;//
深度学习:CPU和GPU算力
壹十壹
深度学习 深度学习 gpu算力 人工智能
一、算力“算力”(ComputingPower)通常是指计算机或计算系统执行计算任务的能力。它是衡量系统处理数据、运行算法以及执行计算任务效率的重要指标。根据上下文,算力可以在以下几种场景中具体化:1.单机算力CPU算力:中央处理器的计算能力,通常用核心数量(cores)、时钟频率(GHz)、以及每秒浮点运算次数(FLOPS)等指标衡量。GPU算力:图形处理单元用于并行处理的能力,尤其是在深度学习
PointPillars:数据预处理
壹十壹
激光雷达感知 深度学习 人工智能 神经网络 python c++
在PointPillars算法中,将点云划分为点柱(Pillars)是核心步骤之一,用于将稀疏点云数据转换为规则的张量表示,方便后续2D卷积操作。以下是点云划分为点柱的具体方法和实现步骤:1.点云划分为网格将3D空间划分为规则的网格,形成柱状区域(Pillars)。操作步骤:定义网格范围和分辨率:确定点云的空间范围,例如:Xmin,Xmax,Ymin,Ymax,Zmin,ZmaxX_{\text{
FFplay文档解读-27-视频过滤器二
【零声教育】音视频开发进阶
音视频开发 程序员 编程 音视频 ffmpeg 运维 c++ android
29.11boxblur将boxblur算法应用于输入视频。它接受以下参数:luma_radius,lrluma_power,lpchroma_radius,crchroma_power,cpalpha_radius,aralpha_power,ap接下来的选项的描述如下:luma_radius,lrchroma_radius,cralpha_radius,ar设置用于模糊相应输入平面的框半径的表
递推算法
aab__
算法
递推算法递推法的概念递推法是一种重要的数学方法,在数学的各个领域中都有广泛的运用,也是计算机用于数值计算的一个重要算法。这种算法特点是:一个问题的求解需一系列的计算,在已知条件和所求问题之间总存在着某种相互联系的关系,在计算时,如果可以找到前后过程之间的数量关系(即递推式),那么,从问题出发逐步推到已知条件,此种方法叫逆推。无论顺推还是逆推,其关键是要找到递推式。这种处理问题的方法能使复杂运算化为
盲签名算法的原理与C语言实现
c密码学信息安全加密解密
0x01概述盲签名(BlindSignature)是由Chaum,David提出的一种数字签名方式,其中消息的内容在签名之前对签名者是不可见的(盲化)。经过盲签名得到的签名值可以使用原始的非盲消息使用常规数字签名验证的方式进行公开验证。盲签名可以有效的保护隐私,其中签名者和消息作者不同,在电子投票系统和数字现金系统中会被使用。盲签名常常被类比成下面的场景:Alice想让Bob在自己的文件上签名,但
《 YOLOv5、YOLOv8、YOLO11训练的关键文件:data.yaml文件编写全解》
空云风语
人工智能 YOLO 机器视觉 目标跟踪 人工智能 计算机视觉 YOLO
走进YOLOv5、YOLOv8、YOLO11的data.yaml在计算机视觉领域的广袤星空中,目标检测无疑是一颗璀璨的明星,它广泛应用于自动驾驶、智能安防、工业检测、医疗影像分析等众多关键领域,发挥着不可或缺的作用。而YOLO系列算法,更是以其独特的“一次看全(YouOnlyLookOnce)”理念和卓越的性能,在目标检测领域中独树一帜,成为了众多研究者和开发者的首选工具。从最初的YOLOv1横空
【LLM】从零开始实现 LLaMA3
FOUR_A
LLM 人工智能 机器学习 大模型 llama 算法
分词器在这里,我们不会实现一个BPE分词器(但AndrejKarpathy有一个非常简洁的实现)。BPE(BytePairEncoding,字节对编码)是一种数据压缩算法,也被用于自然语言处理中的分词方法。它通过逐步将常见的字符或子词组合成更长的词元(tokens),从而有效地表示文本中的词汇。在自然语言处理中的BPE分词器的工作原理如下:初始化:首先,将所有词汇表中的单词分解为单个字符或符号。例
.NET 6 WebApi使用JWT
wenqi.xu
.net .netcore
JWT(JsonWebToken)jwt是一种用于身份验证的开放标准,他可以在网络之间传递信息,jwt由三部分组成:头部,载荷,签名。头部包含了令牌的类型和加密算法,载荷包含了用户的信息,签名则是对头部和载荷的加密结果。jwt鉴权验证是指在用户登录成功后,服务器生成一个jwt令牌并返回给客户端,客户端在后续的请求中携带该令牌,服务通过令牌的签名来确定用户的身份和权限。这种方式可以避免在每个请求中都
qt c++线程中的同步和异步
我要进步!
qt c++
一、线程同步用于协调多个线程对共享资源的访问,避免竞态条件。常用工具:QMutex(互斥锁)保护临界区,确保一次仅一个线程访问资源。QMutexmutex;intsharedData=0;voidThread::run(){mutex.lock();sharedData++;//安全操作mutex.unlock();}QMutexLocker自动管理锁生命周期:{QMutexLockerlocke
如果,你想找 AI大模型相关的工作,这三个建议你一定要看!
我爱学大模型
人工智能 chatgpt AI大模型 AI 大模型入门 转行 程序员
01各种大厂小厂创业团队和AI擦边的面试难度,由难到简单,依次是:大模型算法(⭐⭐⭐⭐⭐)模型部署加速(⭐⭐⭐⭐)RAG等相关技术(⭐⭐⭐)纯应用(⭐⭐)Prompt工程师等其他自媒体(⭐)会简单应用就行02这结果方向,B站找几个视频看看,这里推荐用Qwen7B,开源的模型,一个3060都能跑。例如这个,如何微调Qwen开源模型。https://www.bilibili.com/video/BV1
ES6解构赋值详解
漫天转悠
ES6 es6 前端 ecmascript
ES6解构赋值详解ES6解构赋值是JavaScript语言的一项强大特性,它允许从数组或对象中提取数据,并将其赋值给变量。这一特性不仅简化了代码,提高了可读性,还增强了代码的灵活性。本文将详细介绍ES6解构赋值的基本概念、语法、应用场景以及一些高级用法。1.基本概念解构赋值是对赋值运算符的扩展。它允许按照一定的模式,从数组或对象中提取值,并赋值给变量。这种语法使得从复杂数据结构中提取数据变得更加简
关联规则算法:揭秘数据中的隐藏关系,从理论到实战
秋声studio
机器学习算法详解 关联规则算法 数据挖掘 Apriori算法 FP-Growth算法 大数据优化 数据预处理 增量式更新
引言在当今数据驱动的时代,如何从海量数据中挖掘出有价值的信息成为了各行各业的核心挑战。关联规则算法作为数据挖掘领域的重要工具,能够帮助我们发现数据中隐藏的关联关系,从而为决策提供支持。无论是电商平台的商品推荐,还是医疗领域的疾病诊断,关联规则算法都展现出了强大的应用潜力。本文将从基础概念出发,逐步深入探讨关联规则算法的核心原理、经典算法及其优化策略。无论你是数据挖掘的初学者,还是希望进一步了解关联
大语言模型(LLM)入门学习路线图_llm教程,从零基础到精通,理论与实践结合的最佳路径!
AGI学习社
语言模型 学习 人工智能 LLM 大模型 大数据 自然语言处理
Github项目上有一个大语言模型学习路线笔记,它全面涵盖了大语言模型的所需的基础知识学习,LLM前沿算法和架构,以及如何将大语言模型进行工程化实践。这份资料是初学者或有一定基础的开发/算法人员入门活深入大型语言模型学习的优秀参考。这份资料重点介绍了我们应该掌握哪些核心知识,并推荐了一系列优质的学习视频和博客,旨在帮助大家系统性地掌握大型语言模型的相关技术。大语言模型(LargeLanguageM
C 语言中的数组详解
812503533
c语言 java 开发语言
在C语言中,数组是一种非常基础且常用的数据结构。数组是存储一组相同类型元素的集合,允许我们以统一的方式访问和操作这些元素。C语言中的数组不仅在编程中使用广泛,而且它的灵活性和效率使得它成为了许多算法实现的基础。本篇文章将深入分析C语言中的一维数组,包括定义、存储方式、操作方式、常见问题等等,所有的数据结构都可以从这几个方面来学习。1.数组的定义与存储方式1.1一维数组的定义数组的定义方式包括数组大
【春招笔试真题】饿了么2025.03.07-开发岗真题
春秋招笔试突围
最新互联网春秋招试题合集 java 算法 网络
饿了么2025.03.07-开发岗题目1️⃣:统计01串中0和1的个数,通过计算可能的交换方式确定不同字符串数量2️⃣:使用模板匹配技术识别验证码图片中的"#"符号分布模式3️⃣:构建字典树(Trie)优化异或查询,实现高效的数字黑板游戏整体难度这套题目整体难度适中,由简到难逐步递进:第一题是基础的计数问题,需要理解交换操作的特性第二题是模式识别问题,需要实现模板匹配第三题是高级数据结构应用,需要
C++ time(0)函数
宁玉AC
c学习
time(0)函数返回当前格林尼治标准时间与格林尼治标准时间1970年0分0秒的时间间隔。头文件#include//问题:得到当前时间。#include#includeusingnamespacestd;intmain(){inttotalSeconds=time(0);intcurrentSeconds=totalSeconds%60;inttotalMinutes=totalSeconds/6
C++随机数
宁玉AC
c学习 c++ 开发语言
目录一、名著参考二、详解1.rand()函数2.time(0)3.srand(time(0))4.获取指定范围内的随机数(含指定位数)一、名著参考可以使用cstdlib头文件中的rand()函数来获得随机整数;这个函数返回0~RAND_MAX之间的随机整数;rand()函数生成的是伪随机数。即每次在同一个系统上执行这个函数的时候,rand()函数生成同一序列的数。rand()函数的算法使用一个叫种
C++11之列表初始化
Octopus2077
c++ 学习 笔记
发展历史C++11是C++的第⼆个主要版本,并且是从C++98起的最重要更新。它引⼊了⼤量更改,标准化了既有实践,并改进了对C++程序员可⽤的抽象。在它最终由ISO在2011年8⽉12⽇采纳前,⼈们曾使⽤名称“C++0x”,因为它曾被期待在2010年之前发布。C++03与C++11期间花了8年时间,故⽽这是迄今为⽌最⻓的版本间隔。从那时起,C++有规律地每3年更新⼀次。列表初始化(注意区分列表初始
三种优化算法
旅者时光
算法 算法 python 开发语言
本文将总结遗传算法、粒子群算法、模拟退火三种优化算法的核心思路,并使用python完整实现。实际上,越来越多的优秀算法已经被封装为一个易用的接口。很多时候,一行代码就能实现我们的需求。但了解这些算法的基本逻辑,能够使用最基本的代码实现它。无论对于提升我们的编程能力还是解决问题的能力,都会大有裨益。甚至,改变我们思考问题的方式。1、遗传算法遗传算法,顾名思义,就是借鉴了生物通过遗传变异来逐渐适应环境
蓝桥杯冲击省一必刷题单(一)
小咖拉眯
蓝桥杯 蓝桥杯 java 算法 数据结构
此题单为算法基础精选题单,包含蓝桥杯常考考点以及各种经典算法,可以帮助你打牢基础,查漏补缺。本题单目标是冲击蓝桥杯省一国一,团体程序天梯赛个人国三、XCPC区域赛铜/银奖前言本次题单重点关注日期问题,进制转换问题,排序问题,其中日期问题和进制转换问题,几乎是必考题,几乎每年蓝桥杯都能看到,大家需要重点掌握。日期问题:蓝桥杯热门考点,基本每年省赛必考。进制转换问题:与日期一样蓝桥杯热门考点,基本每年
Vue3 基础教程:从入门到实践 (保姆级教学)
前段技术人
学习 前端 vue.js vue
一、Vue3简介Vue.js是一款用于构建用户界面的JavaScript框架,而Vue3作为其最新的主要版本,带来了诸多令人瞩目的改进与新特性,使其在前端开发领域备受青睐。(一)Vue3的优势性能提升:Vue3重写了虚拟DOM算法,显著提高了挂载、更新和渲染的速度。在处理大型列表或频繁数据更新的场景时,Vue3的表现更为出色,能够为用户带来更流畅的交互体验。例如,一个包含大量商品信息的电商产品列表
刷题前必学!二叉树!用JavaScript学数据结构与算法
JavaScript算法与数据结构-HowieCong务必要熟悉JavaScript使用再来学!一、树是什么?数据结构中的树,对于现实世界中的树简化——树根抽象为“根节点”,树枝抽象为“边”,树枝的两个端点抽象为“结点”,树叶抽象为“叶子结点”计算机中的树如下:二、树的重点树的层次计算规则:根结点所在的那一层为第一层,其子节点为第二层,以此类推结点和树的高度计算规则:叶子结点高度为1,每向上一层
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