您的位置:首页 > 其它

线段树合集 II

2013-11-20 19:39 204 查看

hdu 4553 约会安排

段更新里稍微复杂的应用,需要设置多个判断标志,当时比赛的时候没做出来,还是挺烦人的

hdu 3397 Sequence operation

题目比较烦人,考察对线段树的理解
#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
// hdu 3397
const int MAXN = 200005;
#define ll (root<<1)
#define rr (ll|1)
#define lson l,m,ll
#define rson m+1,r,rr
#define mid m=(l+r)>>1
int num[MAXN];
struct node
{
int sum[2];
int lf[2], rt[2], mx[2];
int sn;
int l, r;
int len;
}nd[MAXN<<2];
void solve(node & a, node & b, node & c, int wori = 0)
{
for (int nima = wori; nima < 2; ++nima)
{
a.sum[nima] = b.sum[nima] + c.sum[nima];
a.mx[nima] = max(b.mx[nima], c.mx[nima]);
if (b.rt[nima] && c.lf[nima])
{
int tp = b.rt[nima] + c.lf[nima];
a.mx[nima] = max(a.mx[nima], tp);
if (b.lf[nima] == b.len)
a.lf[nima] = tp;
else
a.lf[nima] = b.lf[nima];
if (c.lf[nima] == c.len)
a.rt[nima] = tp;
else
a.rt[nima] = c.rt[nima];
}
else
{
a.lf[nima] = b.lf[nima];
a.rt[nima] = c.rt[nima];
}
}
}
void build (int l, int r, int root)
{
nd[root].sn = -1;
nd[root].l = l; nd[root].r = r;
nd[root].len = r-l+1;
if (l == r)
{
if (num[l] == 1)
{
nd[root].sum[1] = 1; nd[root].sum[0] = 0;
nd[root].lf[1] = nd[root].rt[1] = nd[root].mx[1] = 1;
nd[root].lf[0] = nd[root].rt[0] = nd[root].mx[0] = 0;
}
else
{
nd[root].sum[1] = 0; nd[root].sum[0] = 1;
nd[root].lf[1] = nd[root].rt[1] = nd[root].mx[1] = 0;
nd[root].lf[0] = nd[root].rt[0] = nd[root].mx[0] = 1;
}
return;
}
int mid;
build(lson);
build(rson);
solve(nd[root], nd[ll], nd[rr]);
}
void pushDown(int root)
{
if (nd[root].sn == -1) return;
if (nd[root].sn == 0)
{
nd[ll].sum[1] = nd[rr].sum[1] = 0;
nd[ll].sum[0] = nd[ll].len;
nd[rr].sum[0] = nd[rr].len;
nd[rr].lf[1] = nd[rr].rt[1] = nd[rr].mx[1] = nd[ll].lf[1] = nd[ll].rt[1] = nd[ll].mx[1] = 0;
nd[rr].lf[0] = nd[rr].rt[0] = nd[rr].mx[0] = nd[rr].len;
nd[ll].lf[0] = nd[ll].rt[0] = nd[ll].mx[0] = nd[ll].len;
nd[ll].sn = nd[rr].sn = 0;
}
else if (nd[root].sn == 1)
{
nd[ll].sum[0] = nd[rr].sum[0] = 0;
nd[ll].sum[1] = nd[ll].len;
nd[rr].sum[1] = nd[rr].len;
nd[rr].lf[0] = nd[rr].rt[0] = nd[rr].mx[0] = nd[ll].lf[0] = nd[ll].rt[0] = nd[ll].mx[0] = 0;
nd[rr].lf[1] = nd[rr].rt[1] = nd[rr].mx[1] = nd[rr].len;
nd[ll].lf[1] = nd[ll].rt[1] = nd[ll].mx[1] = nd[ll].len;
nd[ll].sn = nd[rr].sn = 1;
}
else
{
for (int a = ll; a <= rr; ++a)
{
swap(nd[a].sum[0], nd[a].sum[1]);
swap(nd[a].lf[0], nd[a].lf[1]);
swap(nd[a].rt[0], nd[a].rt[1]);
swap(nd[a].mx[0], nd[a].mx[1]);
switch (nd[a].sn)
{
case -1: nd[a].sn = 2; break;
case 0: nd[a].sn = 1; break;
case 1: nd[a].sn = 0; break;
case 2: nd[a].sn = -1; break;
}
}
}
nd[root].sn = -1;
}
void change(int x, int y, int c, int l, int r, int root)
{
if (nd[root].sum[c] == nd[root].len) return;
if (x <= l && y>= r)
{
node &k = nd[root];
k.sn = c;
k.sum[c] = k.len; k.sum[1-c] = 0;
k.lf[c] = k.rt[c] = k.mx[c] = k.len;
k.lf[1-c] = k.rt[1-c] = k.mx[1-c] = 0;
return;
}
pushDown(root);
int mid;
if (x <= m) change(x, y, c, lson);
if (y > m) change(x, y, c, rson);
solve(nd[root], nd[ll], nd[rr]);
}
void mreverse(int x, int y, int l, int r, int root)
{
if (x<= l && y>= r)
{
node &k = nd[root];
swap(k.sum[0], k.sum[1]);
swap(k.lf[0], k.lf[1]);
swap(k.rt[0], k.rt[1]);
swap(k.mx[0], k.mx[1]);
switch (k.sn)
{
case -1: k.sn = 2; break;
case 0: k.sn = 1; break;
case 1: k.sn = 0; break;
case 2: k.sn = -1; break;
}
return;
}
pushDown(root);
int mid;
if (x <= m) mreverse(x,y,lson);
if (y > m) mreverse(x,y,rson);
solve(nd[root], nd[ll], nd[rr]);
}
int querynum1(int x, int y, int l, int r, int root)
{
if (nd[root].sum[1] == nd[root].len) return y-x+1;
if (nd[root].sum[0] == nd[root].len) return 0;
int sum = 0;
if (x <= l && y>= r) return nd[root].sum[1];
pushDown(root);
int mid;
if (y<= m) return querynum1(x,y,lson);
if (x > m) return querynum1(x,y,rson);
return querynum1(x,m,lson)+querynum1(m+1,y,rson);
}
node queryMX1(int x, int y, int l, int r, int root)
{
node res;
if (x <= l && y >= r)
{
return nd[root];
}
pushDown(root);
int mid;
if (y <= m) return queryMX1(x,y,lson);
if (x > m) return queryMX1(x,y,rson);
node a = queryMX1(x,m,lson);
node b = queryMX1(m+1,y,rson);
res.l = a.l; res.r = b.r; res.len = a.len+b.len;
solve(res, a, b, 1);
return res;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int t;
int n, m;
scanf("%d", &t);
while (t--)
{
scanf("%d%d", &n, &m);
for (int i = 0; i< n; ++i)
{
scanf("%d", &num[i]);
}
build(0,n-1,1);
while (m--)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
if (a < 2)
change(b,c,a,0,n-1,1);
else if (a == 2)
mreverse(b,c,0,n-1,1);
else if (a == 3)
printf("%d\n", querynum1(b,c,0,n-1,1));
else
{
node tp = queryMX1(b,c,0,n-1,1);
printf("%d\n", tp.mx[1]);
}
}
}
return 0;
}


hdu 4366 Successor

这道题算是偏向于隐含的线段树,利用插入动态维护某个范围内的最大值,借鉴了别人的方法
#include <cstdio>
#include <vector>
#include <string>
#include <algorithm>
#include <queue>
#include <cstring>
#include <map>
#include <set>
#include <iostream>
#include <cmath>
using namespace std;
// 4366
typedef __int64 LL;
#define ll (rot<<1)
#define rr (ll | 1)
#define mid mm = (l+r)>>1
#define lson l,mm,ll
#define rson mm+1,r,rr
const int MAXN = 50005;
map<int , int > mmp;
int mxnum[MAXN*3];
int all;
struct Edge
{
int to, next;
}edge[MAXN*2];
int head[MAXN], cnt;
void edd(int u, int v)
{
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt++;
}
struct mStaff
{
int id, loya, abili;
bool operator < (const mStaff & a) const
{
if (abili != a.abili) return abili > a.abili;
return id > a.id;
}
}staff[MAXN];
int frm[MAXN], ed[MAXN];
void build(int l, int r, int rot)
{
mxnum[rot] = -1;
if (l == r)	return;
int mid;
build(lson);
build(rson);
}
// 更新到底
void add(int kk, int x, int l, int r, int rot)
{
if (l == r)
{
mxnum[rot] = kk;
return;
}
int mid;
if (x <= mm) add(kk, x, lson);
if (x > mm) add(kk, x, rson);
mxnum[rot] = max(mxnum[ll], mxnum[rr]);
}
int query(int x, int y, int l, int r, int rot)
{
if (x <= l && y >= r )
{
return mxnum[rot];
}
int mid;
int s1 = -1, s2 = -1;
if (x <= mm) s1 = query(x, y, lson);
if (y > mm) s2 = query(x, y, rson);
return max(s1, s2);
}
void dfs(int u)
{
frm[u] = all++;
for (int i = head[u]; ~i; i = edge[i].next)	dfs(edge[i].to);
ed[u] = all-1;
}
int res[MAXN];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int t;
scanf("%d", &t);
while (t--)
{
int n, m;
scanf("%d%d", &n, &m);
cnt = 0; all = 0;
memset(head, -1, sizeof head);
mmp.clear();
for (int i = 1; i < n; ++i)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
edd(a, i);
staff[i].id = i;
staff[i].loya = b;
staff[i].abili = c;
mmp[b] = i;
}
sort(staff+1, staff+n);
dfs(0);
build(0, n-1, 1);
int k;
for (int i = 1; i< n; i = k)
{
k = i;
while (k < n && staff[k].abili == staff[i].abili)
{
int j = staff[k].id;
int lo = query(frm[j], ed[j], 0, n-1, 1);
if (lo == -1) res[j] = -1;
else res[j] = mmp[lo];
++k;
}
k = i;
while (k < n && staff[k].abili == staff[i].abili)
{
int j = staff[k].id;
add(staff[k].loya, frm[j], 0, n-1, 1);
++k;
}
}
while (m--)
{
int a;
scanf("%d", &a);
printf("%d\n", res[a]);
}
}
return 0;
}


hdu 4325 Flowers

线段树中数据离散化的应用
#include <cstdio>
#include <vector>
#include <string>
#include <algorithm>
#include <queue>
#include <cstring>
#include <map>
#include <set>
#include <iostream>
#include <cmath>
using namespace std;
typedef __int64 LL;
#define ll (rot<<1)
#define rr (ll | 1)
#define mid mm = (l+r)>>1
#define lson l,mm,ll
#define rson mm+1,r,rr
const int MAXN = 200005;
int n, m;
int ttm[MAXN];
map<int, int> mmp;
struct mNode
{
int u, v;
}flower[MAXN];
int duan[MAXN*6], sz[MAXN*6];
void build(int l, int r, int rot)
{
duan[rot] = 0; sz[rot] = 0;
if (l == r) return;
int mid;
build(lson);
build(rson);
}
void pushDown(int rot)
{
if (!sz[rot]) return;
duan[ll] += sz[rot]; duan[rr] += sz[rot];
sz[ll] += sz[rot]; sz[rr] += sz[rot];
sz[rot] = 0;
}
void add(int x, int y, int l, int r, int rot)
{
if (x<= l && y>= r)
{
duan[rot]++; sz[rot]++;
return;
}
pushDown(rot);
int mid;
if (x <= mm) add(x, y, lson);
if (y > mm) add(x, y, rson);
duan[rot] = duan[ll] + duan[rr];
}
int query(int x, int l, int r, int rot)
{
if (l == r) return duan[rot];
pushDown(rot);
int mid;
if (x <= mm) return query(x, lson);
else return query(x, rson);
}
int ques[MAXN];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int t;
scanf("%d", &t);
for (int _ = 1; _ <= t; ++_)
{
printf("Case #%d:\n", _);
scanf("%d%d", &n, &m);
int all = 0;
for (int i = 0; i< n; ++i)
{
int a, b;
scanf("%d%d", &a, &b);
flower[i].u = a; flower[i].v = b;
ttm[all++] = a; ttm[all++] = b;
}
for (int j = 0; j< m; ++j)
{
int a;
scanf("%d", &a);
ques[j] = a;
ttm[all++] = a;
}
int cnt = 1;
sort(ttm, ttm+all);
all = unique(ttm, ttm+all) - ttm;
for (int i = 0; i< all; ++i)
{
mmp[ttm[i]] = i;
}
build(0, all-1, 1);
for (int i = 0; i< n; ++i)
{
int a = mmp[flower[i].u];
int b = mmp[flower[i].v];
add(a, b, 0, all-1, 1);
}
for (int i = 0; i< m; ++i)
{
printf("%d\n", query(mmp[ques[i]], 0, all-1, 1));
}
}
return 0;
}


hdu 4391 Paint The Wall

线段树成段更新,成段查询

#include <cstdio>
#include <vector>
#include <string>
#include <algorithm>
#include <queue>
#include <cstring>
#include <map>
#include <set>
#include <iostream>
#include <cmath>
using namespace std;
typedef __int64 LL;
#define ll (rot<<1)
#define rr (ll | 1)
#define mid mm = (l+r)>>1
#define lson l,mm,ll
#define rson mm+1,r,rr
const int MAXN = 200005;
int n, m;
int mxc[MAXN*3], mnc[MAXN*3], sz[MAXN*3];
int colr[MAXN];
void build(int l, int r, int rot)
{
sz[rot] = 0;
if (l == r)
{
mxc[rot] = mnc[rot] = colr[l];
return;
}
int mid;
build(lson); build(rson);
mxc[rot] = max(mxc[ll], mxc[rr]);
mnc[rot] = min(mnc[ll], mnc[rr]);
}
void pushDown(int rot)
{
if (sz[rot])
{
sz[rot] = 0;
mxc[ll] = mxc[rr] = mxc[rot];
mnc[ll] = mnc[rr] = mnc[rot];
sz[ll] = sz[rr] = 1;
}
}
void update(int c, int x, int y, int l, int r, int rot)
{
if (c == mxc[rot] && c == mnc[rot]) return;
if (x <= l && y >= r)
{
mxc[rot] = mnc[rot] = c;
sz[rot] = 1;
return;
}
pushDown(rot);
int mid;
if (x <= mm ) update(c, x, y, lson);
if (y > mm) update(c, x, y, rson);
mxc[rot] = max(mxc[ll], mxc[rr]);
mnc[rot] = min(mnc[ll], mnc[rr]);
}
int query(int c, int x, int y, int l, int r, int rot)
{
if (c < mnc[rot] || c > mxc[rot]) return 0;
if (c == mxc[rot] && c == mnc[rot]) return (y-x+1);
if (l == r) return mxc[rot] == c;
pushDown(rot);
int mid;
if (y <= mm) return query(c, x, y, lson);
else if (x > mm) return query(c, x, y, rson);
else
return query(c, x, mm, lson) + query(c, mm+1, y, rson);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = 0; i< n; ++i)
{
scanf("%d", colr+i);
}
build(0, n-1, 1);
while (m--)
{
int a, b, c, d;
scanf("%d%d%d%d", &a, &b, &c, &d);
if (a == 1)	update(d, b, c, 0, n-1, 1);
else printf("%d\n", query(d, b, c, 0, n-1, 1));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: