zoukankan      html  css  js  c++  java
  • CF901C. Bipartite Segments

    n<=300000,m<=300000的图,图上只有奇环,q<=300000个询问每次问:一个区间内有多少个子区间,满足只保留编号在该区间的点以及他们之间的边,可以构成一个二分图。

    终于走出了第一步。。Pi--从点i开始往前延伸最早到哪里就不是二分图了。由于这个数组是单调的,只要这个数组求出来就可以回答询问:每次回答询问时,输出$sum_{i=L}^{R} Max(L-1,P_i)$即可。

    然后就是这个数组怎么求了。。要支持删除点、插入点、查询是不是二分图。。LCT??并查集??动态图??懵逼。。。

    然而题目有特殊性质。。只有奇环就是没有环套环的意思啦,如果有环套环肯定是有偶环的,然后在一个环内,最大编号a,最小编号b,那么相当于对$[a,n]$区间的P数组对b取个Max。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 #include<stdlib.h>
     5 //#include<queue>
     6 //#include<math.h>
     7 //#include<time.h>
     8 //#include<iostream>
     9 using namespace std;
    10 
    11 int n,m,q;
    12 #define maxn 300011
    13 #define maxm 600011
    14 struct Edge{int to,next;};
    15 struct Graph
    16 {
    17     Edge edge[maxm]; int first[maxn],le;
    18     Graph() {le=2; memset(first,0,sizeof(first));}
    19     void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;}
    20     void insert(int x,int y) {in(x,y); in(y,x);}
    21 }g,bg;
    22 
    23 #define LL long long
    24 int p[maxn]; LL sum[maxn];
    25 
    26 int dfn[maxn],low[maxn],Time=0,sta[maxn],top=0,tag[maxn]; bool insta[maxn];
    27 void tarjan(int x,int fa)
    28 {
    29 //    cout<<"tarjan"<<x<<endl;
    30     dfn[x]=low[x]=++Time;
    31     sta[++top]=x; insta[x]=1;
    32     for (int i=g.first[x];i;i=g.edge[i].next)
    33     {
    34         const Edge &e=g.edge[i]; if (e.to==fa) continue;
    35         if (!dfn[e.to]) tarjan(e.to,x),low[x]=min(low[x],low[e.to]);
    36         else if (insta[e.to]) low[x]=min(low[x],dfn[e.to]);
    37     }
    38     if (dfn[x]==low[x])
    39     {
    40         int Min=0x3f3f3f3f,Max=0;
    41         while (sta[top]!=x) Min=min(Min,sta[top]),Max=max(Max,sta[top]),insta[sta[top]]=0,top--;
    42         Min=min(Min,x); Max=max(Max,x); top--; insta[x]=0;
    43         if (Min!=Max) tag[Max]=max(tag[Max],Min);
    44     }
    45 }
    46 
    47 int main()
    48 {
    49     scanf("%d%d",&n,&m);
    50     for (int i=1,x,y;i<=m;i++)
    51     {
    52         scanf("%d%d",&x,&y);
    53         g.insert(x,y);
    54     }
    55     
    56     for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i,0);
    57     int now=0;
    58     for (int i=1;i<=n;i++) now=max(now,tag[i]),p[i]=now;
    59 //    for (int i=1;i<=n;i++) cout<<p[i]<<' ';cout<<endl;
    60     
    61     for (int i=1;i<=n;i++) sum[i]=sum[i-1]+p[i];
    62     scanf("%d",&q);
    63     while (q--)
    64     {
    65         int x,y; scanf("%d%d",&x,&y);
    66         int L=x,R=y+1;
    67         while (L<R)
    68         {
    69             const int mid=(L+R)>>1;
    70             if (p[mid]>=x) R=mid;
    71             else L=mid+1;
    72         }
    73         printf("%lld
    ",-1ll*(x-1)*(L-x)-(sum[y]-sum[L-1])+1ll*(x+y)*(y-x+1)/2);
    74     }
    75     return 0;
    76 }
    View Code
  • 相关阅读:
    Office365常用的命令(持续更新中)
    7:OracleRAC安装配置(19C)
    5:安装配置 Oracle18C
    课程7:邮箱的备份恢复
    课程6: powershell运维
    Exchange2013之HTTP重定向
    Powershell运维:导出Exchange系统里面所有用户的邮箱
    灾难恢复:恢复已经删除的邮箱(AD账号也被删除,14天内)
    灾难恢复:恢复丢失的exchange服务器
    2:Oracle体系结构(物理结构)
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8123994.html
Copyright © 2011-2022 走看看