• JZOJ5919 逛公园


    Description

               琥珀色黄昏像糖在很美的远方,思念跟影子在傍晚一起被拉长……
    Description
          小 B 带着 GF 去逛公园,公园一共有 n 个景点,标号为 1 . . . n。景点之间有 m 条路径相连。
          小 B 想选择编号在一段区间 [l, r] 内的景点来游玩,但是如果这些景点的诱导子图形成了环,那么 GF 将会不高兴。
          小 B 给出很多个询问 [x, y],想让你求有多少个区间 [l, r] 满足 x ≤ l, r ≤ y 且不会使 GF不高兴。

    Input

    第一行为两个整数 n, m,表示景点和路径的数量。
    第 2 . . . m + 1 行每行两个整数 ui, vi 表示第 i 路径的两端。
    第 m + 2 行是一个整数 q 表示询问的个数,接下来 m 行每行两个整数 xi, yi 表示询问。

    Output

    q 行,每行一个整数表示答案。

    Sample Input

    8 9
    1 2
    2 3
    3 1
    4 5
    5 6
    6 7
    7 8
    8 4
    7 2
    3
    1 8
    1 4
    3 8

    Sample Output

    27
    8
    19

    Data Constraint

    对于 30% 的数据,n, m ≤ 100。
    对于另外 10% 的数据,n = m + 1。
    对于另外 10% 的数据,n = m
    对于 100% 的数据,n, m ≤ 3 × 10^5, xi ≤ yi,不存在重边、自环,不存在一条边同时存在于两个不同的简单环。

    Hint

    诱导子图:子图 G′ = (V′, E′),原图 G = (V, E)。V′ 是 V 的子集,E′ = {(u, v)|u, v ∈V′,(u, v) ∈ E}

    Solution

      我们先 DFS 出图的每一个环,得到环上编号最小和最大的节点,那么合法的区间一定不 能同时跨过这两个点。于是我们搞出一个 R 数组,R[i] 表示以 i 作为左端点时右端点最右可 以到哪个位置。R 数组显然是单调递增的。

      对于询问 l, r,我们二分出一个位置 i 满足 max-R[l . . . i − 1] ≤ r,min-R[i . . . r] ≥ r,直接计算即可,那么左边的贡献就可以用前缀和统计,右边就是一个等差数列。

     1 #include<cstdio>
     2 #define N 500007
     3 #define LL long long
     4 using namespace std;
     5 struct arr{
     6     int x,y,next;
     7 }edge[N*2];
     8 int n,m,q,ls[N];
     9 LL rr[N],a[N],r[N],f[N];
    10 
    11 LL max(LL x,LL y){
    12     if (x>y) return x;
    13     return y;
    14 }
    15 
    16 LL min(LL x,LL y){
    17     if (x<y) return x;
    18     return y;
    19 }
    20 
    21 int add(LL x,LL y,int e){
    22     edge[e].x=x; edge[e].y=y;
    23     edge[e].next=ls[edge[e].x]; ls[edge[e].x]=e;
    24     edge[--e].x=y; edge[e].y=x;
    25     edge[e].next=ls[edge[e].x]; ls[edge[e].x]=e;
    26 }
    27 
    28 int ss(LL x,LL w,LL l){
    29     a[w]=x;    
    30     f[x]+=1;
    31     if (f[x]!=1){
    32         LL e=w,mi=x,ma=x;
    33         while (a[e-1]!=x){
    34             mi=min(mi,a[--e]);
    35             ma=max(ma,a[e]);
    36         }
    37         if (r[mi]!=0) r[mi]=min(r[mi],ma);
    38         else r[mi]=ma;
    39         return 0;
    40     }
    41 
    42     LL i=ls[x];
    43     while (i!=0){
    44         if (edge[i].y!=l){
    45             ss(edge[i].y,w+1,x);
    46             f[edge[i].y]-=1;
    47         }
    48         i=edge[i].next;
    49     }
    50 }
    51 
    52 int main(){
    53     scanf("%d%d",&n,&m);
    54     LL x,y;
    55     for (int i=1;i<=m;i++){
    56         scanf("%lld%lld",&x,&y);
    57         add(x,y,i*2);
    58     }
    59     ss(1,1,0);
    60     LL k=n;
    61     for (int i=n;i>=1;i--){
    62         if (r[i]!=0) k=min(r[i]-1,k);
    63         r[i]=k;
    64     }
    65     for (int i=1;i<=n;i++)
    66         rr[i]=rr[i-1]+(r[i]-i+1);
    67     scanf("%d",&q);
    68     for (int i=1;i<=q;i++){
    69         scanf("%d%d",&x,&y);
    70         LL lx=x,ly=y;
    71         while (lx<ly){
    72             LL mid=(lx+ly)/2;
    73             if (r[mid]>=y)
    74                 ly=mid;
    75             else lx=mid+1;
    76         }
    77         if (r[lx]<y) lx++;
    78         LL ans=1ll*(rr[lx-1]-rr[x-1]);
    79         ans+=1ll*(y-lx+1)*(y-lx+2)/2;
    80         printf("%lld
    ",ans);
    81     }
    82 }
    View Code
  • 相关阅读:
    debian 中安装GIT
    多核处理器 利用多线程 加速 编译内核 速度
    ubuntu下安装中文输入法(乱码等问题)
    ubuntu 10.04源 更新源列表
    php empty,isset,is_null比较(差异与异同) Leone
    Win 7 各版本的含义 Leone
    Atitit DbServiceV4qb9 数据库查询类库v4 新特性
    Atitit 图像处理之仿油画效果 Oilpaint油画滤镜 水彩画 漫画滤镜 v2
    Atitit 多继承实现解决方案 java c#
    Atitit 基于图片图像 与文档混合文件夹的分类
  • 原文地址:https://www.cnblogs.com/Tokisaki-Kurumi/p/9832506.html
Copyright © 2020-2023  润新知