• hiho#1145 : 幻想乡的日常


    描述

    幻想乡一共有n处居所,编号从1到n。这些居所被n-1条边连起来,形成了一个树形的结构。

    每处居所都居住着一个小精灵。每天小精灵们都会选出一个区间[l,r],居所编号在这个区间内的小精灵一起来完成一项任务。

    特别的,居所相邻的(有边相连的)两个小精灵会自发的组成一队,并且如果a和b相邻b和c相邻,那么a和c也在同一队里面。每天的任务完成之后,队伍就会解散;第二天再根据新的区间组成新的队伍。

    给出每天小精灵们选出的区间,你知道每天组成的队伍数量吗?

    输入

    第一行两个数n和Q(1 <= n, Q <= 100000),表示居所的数目和组队的天数。

    接下来n-1行,每行两个数a和b,表示居所a和b之间有一条边。

    接下来Q行,每行两个数l和r,满足1<=l<=r<=n,为该天小精灵选出的区间。

    输出

    输出Q行,每行一个整数表示该天队伍的数量。

    样例输入

    3 1
    1 2
    2 3
    1 3

    样例输出

    1

    草草看完题,妈妈我不会做啊。再看一遍,原来是一颗树!
    那么一个区间[l,r]的答案就是r-l+1-满足l<=ui<=r&&l<=vi<=r的边的数目。
    那么这就是一个二维偏序模型,离线用个Fenwich什么的就行了。
    #include<cstdio>
    #include<cctype>
    #include<queue>
    #include<stack>
    #include<cstring>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define dwn(i,s,t) for(int i=s;i>=t;i--)
    #define ren for(int i=first[x];i;i=next[i])
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=200010;
    int n,q,u[maxn],v[maxn],ans[maxn],e[maxn];
    struct Query {
        int x,l,r,id,tp;
        bool operator < (const Query& ths) const {return x<ths.x;}
    }Q[maxn];
    int cmp(int x,int y) {return u[x]<u[y];}
    int sumv[maxn];
    int sum(int x) {
        int res=0;
        for(;x;x-=x&-x) res+=sumv[x];
        return res;
    }
    void add(int x) {for(;x<=n;x+=x&-x) sumv[x]++;}
    int main() {
        n=read();q=read();
        rep(i,1,n-1) u[i]=read(),v[i]=read(),e[i]=i;
        rep(i,1,q) {
            int l=read(),r=read();
            Q[i*2-1]=(Query){r,l,r,i,1};
            Q[i*2]=(Query){l-1,l,r,i,-1};
            ans[i]=r-l+1;
        }
        q<<=1;int cur=0;
        sort(Q+1,Q+q+1);sort(e+1,e+n,cmp);
        rep(i,1,q) {
            while(cur<n-1&&u[e[cur+1]]<=Q[i].x) add(v[e[++cur]]);
            ans[Q[i].id]-=Q[i].tp*(sum(Q[i].r)-sum(Q[i].l-1));
        }
        rep(i,1,q>>1) printf("%d
    ",ans[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    Docker
    Docker
    VIM
    Python
    Python
    VIM
    Python
    其他
    Java
    Java
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/4783586.html
Copyright © 2020-2023  润新知