E - Yet Another Tree Query Problem ZOJ - 4008

题目

Yet Another Tree Query Problem
Time Limit: 3 Seconds      Memory Limit: 65536 KB
Given a tree with  vertices, which are numbered by integers from 1 to , there are  queries.

Each query can be described with two integers  and . A vertex  is good, if and only if ; An edge  is good, if and only if both  and  are good. Please print the number of connected components consist of all the good vertices and the good edges.

Input
There are multiple test cases. The first line of the input is an integer  (about 5), indicating the number of test cases. For each test case:

The first line contains two integers  and  (), indicating the number of vertices and the number of queries.

The following  lines each contains two integers  and  (), indicating an edge connecting vertex  and  in the tree.

The following  lines each contains two integers  and  (), indicating a query.

It's guaranteed that the given graph is a tree.

Output
For each query output one line containing one integer, indicating the answer.

Sample Input
2
4 6
1 4
4 3
3 2
1 2
2 3
3 4
1 3
2 4
1 4
3 2
1 3
2 3
1 2
2 3
Sample Output
2
1
1
2
1
1
2
1
Hint
For the six queries in case 1, the connected components are listed as follows:

[1], [2]
[2, 3]
[3, 4]
[1], [2, 3]
[2, 3, 4]
[1, 2, 3, 4]
For the two queries in case 2, the connected components are as follows:

[1], [2]
[2, 3]
Author: WANG, Yuhan
Source: ZOJ Monthly, March 2018
Submit    Status
Copyright @ 2001-2018, Zhejiang University ACM/ICPC Team, All rights reserved.

题目分析:
题目讲的是一颗树,问查询[l,r]区间内,独立的点和边的个数。
这题很巧妙的利用了查询的先后顺序进行答案的排布。

首先要对查询的数组的r侧进行排序,排序后左侧l所在位置标记上1,代表此处的点要换成边。并且要保证r不要超过要查询的范围。
E - Yet Another Tree Query Problem ZOJ - 4008_第1张图片
比如说,q.l = 1 q.r=4
那么我们需要把
1-4,3-4,2-3,1-2
E - Yet Another Tree Query Problem ZOJ - 4008_第2张图片
底线代表被标记

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)

#define mset(var,val) memset(var,val,sizeof(var))

#define test(a) cout<
#define test2(a,b) cout<
#define test3(a,b,c) cout<
const int mod =1e9+7 ;
typedef long long ll;
using namespace std;
const int MAXN = 2e5+10;
int C[MAXN*4];
int n;
int lowbit(int x){
    return x&(-x);
}
int sum(int x){
    int ret = 0;
    while(x>0){
        ret += C[x]; x-=lowbit(x);
    }
    return ret;
}
void add(int x,int d){
    while(x<=n){
        C[x]+=d;
        x+=lowbit(x);
    }
}
vector<int>g[MAXN];
int ans[MAXN];
struct  node
{
    int u,v;
    int id; 
    bool friend operator < (node a,node b){
        if(a.v == b.v){
            return a.ureturn a.vvoid work(){    
    int Q;
    scdd(n,Q);
    mset(C,0);
    int u,v;
    for(int i =0;i<=n;i++)g[i].clear();
    for(int i =0;i1;i++){
            scdd(u,v);
            if(u>v)swap(u,v);
            g[v].push_back(u);
    }
    for(int i =0;iint l=1;
    for(int i =0;iwhile(l<=q[i].v){
            for(int j =0;j1);
            }
            l++;
        }
        ans[q[i].id]=(q[i].v-q[i].u+1)-(sum(q[i].v)-sum(q[i].u-1));
    }
    for(int i =0;iprintf("%d\n",ans[i]);
    }
}
int main(){
    #ifdef local
        freopen("in.txt","r",stdin);
    #endif
    int  t;
    scd(t);
    while(t--){
        work();
    }
}

你可能感兴趣的:(ACM,datastructure,大二下训练赛)