ZOJ 4008 Yet Another Tree Query Problem 树状数组 离线处理

点我看题目
题意:
给出一颗n个点的树 结点编号1-n。
给出一个二元组[l,r] 定义一个结点为好结点 当且仅当 其编号 i 满足 l< i < r 时 i结点为好结点。
两个相邻好结点之间的边为好边。
现在有Q次询问 每次询问给出[l,r]
对于每次询问 求出由好边链接的连通块的个数。

解题思路:
最容易想到就是对每次询问进行一遍DFS,找坏边,然后求连通块的个数, 总复杂度为O(nq)
之后想到 其实连通块的个数等于好点个数减去好边个数。
然后询问很像线段树的询问,联想到区间求和问题。
把所有边全部放在一个一维坐标轴上,那么问题可以转化为两端点都在[l,r] 范围内的边有多少条。
先得到一个最暴力的算法 每次询问 暴力遍历所有边,找其中符合条件的边。 复杂度同样为O(nq)
在想如何使用线段树去优化。
一开始就把所有点都加到线段树里面去,然后再查询的做法很容易可以证明是行不通的。情况太多。
想如何化简问题的情况, 根据以前的题目,联想到排序后进行离线处理求结果。
对于询问和边 都用右端点为关键字排序。
然后在询问过程中添加符合右端点小于询问 r的边, 将之左端点l加入到线段树中。 这样 复杂度就降到了O(qlogn)
然后用线段树写老报错 ,改成树状数组就A了

#include<bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int MAX=(1e5+10)*2;
int tree[MAX],n=MAX;
void add(int x,int num)
{
    for(;x<=n;x+=x&-x)
        tree[x]+=num;
}
int sum(int x)
{
    int answer =0;
    for(;x>0;x-=x&-x)
        answer+=tree[x];
    return answer;
}
class Node{
public:
    int l,r,id;
    bool operator <(const Node &b) const {
        return r<b.r;
    }
} ;
Node node1[MAX];
Node node2[MAX];
int ans[MAX];
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n,q;
        memset(tree,0,sizeof tree);
        scanf("%d %d",&n,&q);
        for(int i=1;i<n;i++){
            scanf("%d %d",&node1[i].l,&node1[i].r);
            if(node1[i].l>node1[i].r) swap(node1[i].l,node1[i].r);
        }
        for(int i=1;i<=q;i++){
            scanf("%d %d",&node2[i].l,&node2[i].r);
            node2[i].id=i;
        }
        sort(node1+1,node1+n);
        sort(node2+1,node2+q+1);
        int tot=1;
        for(int i=1;i<=q;i++){
            int l=node2[i].l,r=node2[i].r;
            //cout<<l<<","<<r<<","<<node2[i].id<<endl;
            while(node1[tot].r<=r && tot<n){
                add(node1[tot].l,1);
                //cout<<"up"<<node1[tot].l<<" "<<node1[tot].r<<endl;
                tot++;
            }
            int sums=sum(r)-sum(l-1);
            ans[node2[i].id]=(r-l+1-sums);
        }
        for(int i=1;i<=q;i++){
            printf("%d\n",ans[i]);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/lifelikes/article/details/79573672
今日推荐