校门外的区间 月下毛景树

P5568 [SDOI2008] 校门外的区间

P4315 月下“毛景树”

分析

这两题放一起是因为,都有对两个懒标记的优先权的调整。

校门外的区间

我们可以将题目的中操作转化为

  • U:B区间覆盖1**
  • I:B区间的补集覆盖0
  • D:B区间覆盖0
  • C:全集范围内01翻转,转到I操作
  • S:B区间范围内01翻转

需要注意的是,区间覆盖与区间反转操作,若进行区间覆盖,则进行前将区间反转的懒标记清空

月下毛景树

树剖+线段树

需要解决的是,区间加与区间覆盖的优先权问题

在进行区间覆盖时,记得将区间加的懒标记清空。

Ac_code

校门外的区间

#include <bits/stdc++.h>
#define maxn 132010
#define ls rt << 1
#define rs rt << 1 | 1
using namespace std;
struct Seg{
	int l, r, cov, tag;
}seg[maxn << 2];
int ans[maxn], n = maxn;
char s[20];

void get(int &l, int &r){
	char c = getchar();
	for (; c != '(' && c != '['; c = getchar());
	int w = c == '('; l = 0;
	for (; !isdigit(c); c = getchar());
	for (; isdigit(c); c = getchar()) l = (l << 1) + (l << 3) + (c ^ 48);
	l <<= 1;
	l += w, r = 0;
	for (; !isdigit(c); c = getchar());
	for (; isdigit(c); c = getchar()) r = (r << 1) + (r << 3) + (c ^ 48);
	r <<= 1;
	for (; c != ')' && c != ']'; c = getchar());
	r -= c == ')';
}

void pushdown(int rt){
	if (seg[rt].cov != -1){
		seg[ls].cov = seg[rs].cov = seg[rt].cov;
		seg[ls].tag = seg[rs].tag = 0;
		seg[rt].cov = -1;
	}
	if (seg[rt].tag){
		seg[ls].tag ^= 1, seg[rs].tag ^= 1;
		seg[rt].tag = 0;
	}
}

void build(int rt, int l, int r){
	seg[rt].l = l, seg[rt]. r = r, seg[rt].cov = -1;
	if (l == r) return;
	int mid = (l + r) >> 1;
	build(ls, l, mid), build(rs, mid + 1, r);
}

void update(int rt, int l, int r, int k){
	if (seg[rt].l > r || seg[rt].r < l || l > r) return;
	if (seg[rt].l >= l && seg[rt].r <= r){
		if (k != 2) seg[rt].cov = k, seg[rt].tag = 0; else seg[rt].tag ^= 1;
		return;
	}
	pushdown(rt);
	update(ls, l, r, k), update(rs, l, r, k);
}

void query(int rt){
	if (seg[rt].l == seg[rt].r){
		ans[seg[rt].l] = seg[rt].cov == -1 ? 0 : seg[rt].cov ^ seg[rt].tag; return;
	}
	pushdown(rt);
	query(ls), query(rs);
}

void print(){
	query(1);
	int flag = 0, Empty = 0;
	for (int i = 0; i <= n; ++i){
		if (ans[i] && !flag){
			flag = Empty = 1;
			if (i & 1) printf("(%d,", (i - 1) >> 1); else printf("[%d,", i >> 1);
		}
		if (!ans[i] && flag){
			flag = 0;
			if (i & 1) printf("%d] ", (i - 1) >> 1); else printf("%d) ", i >> 1);
		}
	}
	if (!Empty) puts("empty set");
}

int main(){
	build(1, 0, n);
	while (scanf("%s", s) != EOF){
		int l, r;
		get(l, r);
		if (s[0] == 'U') update(1, l, r, 1); else
		if (s[0] == 'I') update(1, 0, l - 1, 0), update(1, r + 1, n, 0); else
		if (s[0] == 'D') update(1, l, r, 0); else
		if (s[0] == 'C') update(1, 0, n, 2), update(1, 0, l - 1, 0), update(1, r + 1, n, 0); else
		update(1, l, r, 2);
	}
	print();
	return 0;
}

月下毛景树

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10,M = N*2;
struct Node
{
    int l,r,mx,tag,tag1;
}tr[N<<2];
int h[N],e[M],ne[M],w[M],idx;
int sz[N],son[N],fa[N],dep[N];
int id[N],nw[N],val[N],e2u[M],top[N],cnt;
int n;

void add(int a,int b,int c)
{
    e[idx] = b,ne[idx] = h[a],w[idx] = c,h[a] = idx++;
}

void dfs1(int u,int pa,int depth)
{
    sz[u] = 1,fa[u] = pa,dep[u] = depth;
    for(int i=h[u];~i;i=ne[i])
    {
        int j = e[i];
        if(j==fa[u]) continue;
        dfs1(j,u,depth+1);
        e2u[i/2+1] = j,val[j] = i;
        if(sz[j]>sz[son[u]]) son[u] = j;
        sz[u] += sz[j];
    }
}

void dfs2(int u,int tp)
{
    top[u] = tp,id[u] = ++cnt,nw[cnt] = w[val[u]];
    if(!son[u]) return ;
    dfs2(son[u],tp);
    for(int i=h[u];~i;i=ne[i])
    {
        int j = e[i];
        if(j==fa[u]||j==son[u]) continue;
        dfs2(j,j);
    }
}

void pushup(int u)
{
    tr[u].mx = max(tr[u<<1].mx,tr[u<<1|1].mx);
}

void pushdown(int u)
{
    auto &root = tr[u],&left = tr[u<<1],&right = tr[u<<1|1];
    if(root.tag1)
    {
        left.mx = root.tag1;
        left.tag = 0;
        left.tag1 = root.tag1;
        right.mx = root.tag1;
        right.tag = 0;
        right.tag1 = root.tag1;
        root.tag1 = 0;
    }
    if(root.tag)
    {
        left.mx += root.tag;
        left.tag += root.tag;
        right.mx += root.tag;
        right.tag += root.tag;
        root.tag = 0;
    }
}

void build(int u,int l,int r)
{
    if(l==r)
    {
        tr[u] = {l,r,nw[l],0,0};
        return ;
    }
    tr[u] = {l,r};
    int mid = l + r >> 1;
    build(u<<1,l,mid),build(u<<1|1,mid+1,r);
    pushup(u);
}

void modify1(int u,int l,int r,int x)
{
    if(l<=tr[u].l&&tr[u].r<=r) 
    {
        tr[u].mx = x;
        tr[u].tag = 0;
        tr[u].tag1 = x;
        return ;
    }
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1;
    if(l<=mid) modify1(u<<1,l,r,x);
    if(r>mid) modify1(u<<1|1,l,r,x);
    pushup(u);
}

void modify2(int u,int l,int r,int x)
{
    if(l<=tr[u].l&&tr[u].r<=r)
    {
        tr[u].mx += x;
        tr[u].tag += x;
        return ;
    }
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1;
    if(l<=mid) modify2(u<<1,l,r,x);
    if(r>mid) modify2(u<<1|1,l,r,x);
    pushup(u);
}

int query(int u,int l,int r)
{
    if(l<=tr[u].l&&tr[u].r<=r) return tr[u].mx;
    pushdown(u);
    int res = 0;
    int mid = tr[u].l + tr[u].r >> 1;
    if(l<=mid) res = max(res,query(u<<1,l,r));
    if(r>mid) res = max(res,query(u<<1|1,l,r));
    return res; 
}

int main()
{
    scanf("%d",&n);
    memset(h,-1,sizeof h);
    for(int i=0;i<n-1;i++)
    {
        int u,v,c;scanf("%d%d%d",&u,&v,&c);
        add(u,v,c),add(v,u,c);
    }
    dfs1(1,-1,1);
    dfs2(1,1);
    build(1,1,n);
    char op[7];int u,v,k;
    while(scanf("%s",op))
    {
        if(!strcmp(op,"Stop")) break;
        scanf("%d%d",&u,&v);
        if(!strcmp(op,"Change")) modify1(1,id[e2u[u]],id[e2u[u]],v);
        else if(!strcmp(op,"Cover"))
        {
            scanf("%d",&k);
            while(top[u]!=top[v])
            {
                if(dep[top[u]]<dep[top[v]]) swap(u,v);
                modify1(1,id[top[u]],id[u],k);
                u = fa[top[u]];
            }
            if(u!=v)
            {
                if(dep[u]<dep[v]) swap(u,v);
                modify1(1,id[v]+1,id[u],k);
            }
        } 
        else if(!strcmp(op,"Add"))
        {
            scanf("%d",&k);
            while(top[u]!=top[v])
            {
                if(dep[top[u]]<dep[top[v]]) swap(u,v);
                modify2(1,id[top[u]],id[u],k);
                u = fa[top[u]];
            }
            if(u!=v)
            {
                if(dep[u]<dep[v]) swap(u,v);
                modify2(1,id[v]+1,id[u],k);
            }
        }
        else
        {
            int res = 0;
            while(top[u]!=top[v])
            {
                if(dep[top[u]]<dep[top[v]]) swap(u,v);
                res = max(res,query(1,id[top[u]],id[u]));
                u = fa[top[u]];
            }
            if(u!=v)
            {
                if(dep[u]<dep[v]) swap(u,v);
                res = max(res,query(1,id[v]+1,id[u]));
            }
            printf("%d\n",res);
        }
    }
    return 0;
}
posted @ 2022-05-04 21:17  艾特玖  阅读(34)  评论(0)    收藏  举报