codeforces 343d

题意:一棵树结构上有水,往一个节点加水,那么所有的子节点都会有水,或者排干一个节点的水,那么它的上面的节点都会没水。

用dfs序,数组记录区间内全部有水为1,区间内有没水的点就为0。

倒水:区间更新,排水:单点更新,并更新途中经过的所有点,查询:区间查询。

倒水:区间内所有的点变为有水,就是1,用lazy数组,要下传。

排水:所有节点的dfs序之间的相交只能是包含,并且只被祖先包含。那么在线段树中就将经过的点全部排去。这样祖先节点查询时就为0了,并且无关节点还是有水。不过这样有个BUG,假如开始全有水,如果一个节点排空了立即加水,那么祖先又有水了,实际上是没水,这时将祖先排水就行。

6
2 1
3 1
4 1
4 5
2 6
4
1 1
2 4
1 4
3 1就这。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#include <bitset>
#include <unordered_set>
#define mkp make_pair
using namespace std;
const double EPS=1e-8;
typedef long long lon;
const lon SZ=500010,SSZ=10*SZ,APB=20,INF=0x7FFFFFFF,mod=1000000007;
lon n,bg[SZ],fn[SZ],cnt,arr[SSZ],lazy[SSZ];
lon pre[SZ];
vector<int> mp[SZ];

void release()
{
    
}

void dfs(int x,int p)
{
    bg[x]=++cnt;
    pre[x]=p;
    for(int i=0;i<mp[x].size();++i)
    {
        int to=mp[x][i];
        if(to!=p)
        {
            dfs(to,x);
        }
    }
    fn[x]=cnt;
}

void pushdown(int rt)
{
    if(lazy[rt])
    {
        lazy[rt*2]=lazy[rt*2+1]=1;
        arr[rt*2]=arr[rt*2+1]=1;
        lazy[rt]=0;
    }
}

void pushup(int rt)
{
    arr[rt]=arr[rt*2]*arr[rt*2+1];
}

void update(int ll,int rr,int rt,int ql,int qr)
{
    int mid=(ll+rr)/2;
    pushdown(rt);
    if(ql<=ll&&rr<=qr)
    {
        arr[rt]=1;
        lazy[rt]=1;
        return;
    }
    if(ll>rr)return;
    if(ql<=mid)update(ll,mid,rt*2,ql,qr);
    if(qr>mid)update(mid+1,rr,rt*2+1,ql,qr);
    pushup(rt);
}

void update(int ll,int rr,int rt,int pos)
{
    int mid=(ll+rr)/2;
    pushdown(rt);
    if(ll==rr)
    {
        arr[rt]=0;
        return;
    }
    if(pos<=mid)update(ll,mid,rt*2,pos);
    else update(mid+1,rr,rt*2+1,pos);
    pushup(rt);
}

int qry(int ll,int rr,int rt,int ql,int qr)
{
    //cout<<" "<<ll<<" "<<rr<<endl;
    int mid=(ll+rr)/2;
    pushdown(rt);
    if(ql<=ll&&rr<=qr)
    {
        return arr[rt];
    }
    if(ll>rr)return 1;
    int res1=1,res2=1;
    if(ql<=mid)res1=qry(ll,mid,rt*2,ql,qr);
    if(qr>mid)res2=qry(mid+1,rr,rt*2+1,ql,qr);
    return res1*res2;
}

void init()
{
    cin>>n;
    for(int i=1;i<=n-1;++i)
    {
        int a,b;
        cin>>a>>b;
        mp[a].push_back(b);
        mp[b].push_back(a);
    }
    dfs(1,-1);
}

void work()
{
    int qnum;
    cin>>qnum;
    for(int i=1;i<=qnum;++i)
    {
        int type,x;
        cin>>type>>x;
        if(type==1)
        {
            if(x!=1&&!qry(1,cnt,1,bg[x],fn[x]))update(1,cnt,1,bg[pre[x]]);
            update(1,cnt,1,bg[x],fn[x]);
        }
        else if(type==2)
        {
            update(1,cnt,1,bg[x]);
        }
        else
        {
            //cout<<"3: "<<bg[x]<<" "<<fn[x]<<endl;
            cout<<qry(1,cnt,1,bg[x],fn[x])<<endl;
        }
    }
}

int main()
{
    //std::ios::sync_with_stdio(0);
    //freopen("d:\\2.txt","r",stdin);
    //freopen("d:\\3.txt","w",stdout);
    lon casenum;
    //cin>>casenum;
    //cout<<casenum<<endl;
    //for(lon time=1;time<=casenum;++time)
    //for(lon time=1;scanf("%d%d",&n,&m)!=EOF;++time)
    {
        init();
        work();
        release();
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/gaudar/p/10698052.html
今日推荐