线段树(dfs序建树加区间更新和单点查询)

题目链接:https://cn.vjudge.net/contest/66989#problem/J

记录一下这道折磨了我一天的题,。。。。

具体思路: 具体关系可通过dfs序建树,但是注意,在更新以及查询时的数和你dfs序建成的数是不一样的。因为你dfs序建成的树每个左右区间以及端点会发生不符合建树的条件。但是具体区间的更新还是可以通过新的树进行更新的,但是下属关系还是符合线段树的规则的,区间越大,也就是管理的人越多,也就是端点越往上。

AC代码;

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
# define inf 0x3f3f3f3f
# define maxn 500000+100
# define ll long long
# define lson l,m,rt<<1
# define rson m+1,r,rt<<1|1
vectorwakaka[maxn];
int vis[maxn];
int st[maxn];
int ed[maxn];
bool cover[maxn];
int ans;
int num;
int a[maxn];
void init()
{
    memset(cover,0,sizeof(a));
    memset(vis,0,sizeof(vis));
    memset(st,0,sizeof(st));
    memset(ed,0,sizeof(ed));
    num=0;
}
void cal(int rt,int l,int r)
{
    if(a[rt]==-1||l==r)return ;//必须先判断a[rt]是不是-1,如果是-1.则不能往下更新。
    a[rt<<1]=a[rt<<1|1]=a[rt];
    a[rt]=-1;
}
void dfs(int u)
{
    st[u]=++num;
    int len=wakaka[u].size();
    for(int i=0; i>1;
    if(p<=m)query(p,lson);
    else if(p>m)query(p,rson);
}
void update(int col,int L,int R,int l,int r,int rt)
{
    if(L<=l&&R>=r)
    {
        a[rt]=col;
        return ;
    }
    cal(rt,l,r);
    int m=(l+r)>>1;
    if(L<=m)update(col,L,R,lson);
    if(R>m)update(col,L,R,rson);
}
int main()
{
    int T;
    scanf("%d",&T);
    int t=0;
    while(T--)
    {
        int n,u,v;
        scanf("%d",&n);
        init();
        for(int i=1; i<=n; i++){
        wakaka[i].clear();
        }
        memset(a,-1,sizeof(a));
        for(int i=1; i

 

你可能感兴趣的:(线段树)