校门外的区间 月下毛景树
分析
这两题放一起是因为,都有对两个懒标记的优先权的调整。
校门外的区间
我们可以将题目的中操作转化为
- 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;
}

浙公网安备 33010602011771号