http://codeforces.com/contest/901/problem/C

  codeforces 901C

  首先因为图中没有偶数长度的环,所以:

    1.图中的环长度全是奇数,也就是说,只要这个子图中存在环,那么这个子图肯定是不合法的。

    2.图中任意两个环没有公共边,否则合成的环的长度必然是偶数

  所以用一个dfs可以找到所有环

  然后对于每个环,求出这个环里面的最大值 li 和最小值 ri 。那么显然对于区间 [1,li] 中的任意位置 x,这个数的右区间的取值范围必然小于 ri,

  所以可以通过一个线段树找出所有左节点对应的右节点最大值,这里对于节点 x ,记其对应的右节点最大值为 rib[x]。

  对于q个询问

  设给定询问的左端点为 ql,右端点为 qr

  那么二分找到 [ql,qr]区间中的第一个数,她的右端点最大值大于等于 qr,记这个位置为plc

  那么 [ql,qr] 这个区间可以被分为 [ql,plc-1] [plc,qr],分别计算答案,

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue> using namespace std; typedef long long ll; const int INF=1e9+44;
const int M=3e5+44; struct node{
int u,v;
int next;
}edge[2*M]; queue<int> que;
int head[M],num;
int dg[M]; void addedge(int u,int v)
{
edge[num].u=u;
edge[num].v=v;
edge[num].next=head[u];
head[u]=num++;
} void init()
{
num=0;
memset (head,-1,sizeof(head));
} int n,m;
int tree[M*3],tag[M*3]; void build(int rt,int li,int ri)
{
tag[rt]=INF;
if(li==ri)
{
tree[rt]=n;
return ;
}
int mid=(li+ri)>>1,lc=(rt<<1),rc=(rt<<1)+1;
build(lc,li,mid);
build(rc,mid+1,ri);
tree[rt]=min(tree[lc],tree[rc]);
} void pushdown(int rt,int li,int ri)
{
if(li==ri)
{
tag[rt]=INF;
return ;
}
int mid=(li+ri)>>1,lc=(rt<<1),rc=(rt<<1)+1;
tag[lc]=min(tag[lc],tag[rt]);
tag[rc]=min(tag[rc],tag[rt]);
tag[rt]=INF;
tree[lc]=min(tree[lc],tag[lc]);
tree[rc]=min(tree[rc],tag[rc]);
} void update(int rt,int li,int ri,int lq,int rq,int val) //change to val
{
if(lq<=li && ri<=rq)
{
tag[rt]=min(tag[rt],val);
tree[rt]=min(tree[rt],val);
return ;
}
int mid=(li+ri)>>1,lc=(rt<<1),rc=(rt<<1)+1;
if(tag[rt]!=INF)
pushdown(rt,li,ri);
if(mid>=lq)
update(lc,li,mid,lq,rq,val);
if(mid+1<=rq)
update(rc,mid+1,ri,lq,rq,val);
tree[rt]=min(tree[lc],tree[rc]);
} int query(int rt,int li,int ri,int lq,int rq) //get min val
{
int ret=INF;
if(lq<=li && ri<=rq)
return tree[rt];
int mid=(li+ri)>>1,lc=(rt<<1),rc=(rt<<1)+1;
if(tag[rt]!=INF)
pushdown(rt,li,ri);
if(mid>=lq)
ret=min(ret,query(lc,li,mid,lq,rq));
if(mid+1<=rq)
ret=min(ret,query(rc,mid+1,ri,lq,rq));
return ret;
} int stk[M],lstk,dlt[M],vis[M]; int dfs(int rt,int pa)
{
// cout<<"rt:"<<rt<<endl;
int v;
vis[rt]=1,stk[++lstk]=rt;
for(int i=head[rt];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(v==pa || dlt[v]) continue;
if(vis[v])
{
int li=INF,ri=0;
while(lstk>0)
{
// cout<<stk[lstk]<<" . ";
dlt[stk[lstk]]=1;
li=min(li,stk[lstk]),ri=max(ri,stk[lstk]);
lstk--;
if(stk[lstk+1]==v)
break;
}
// cout<<endl;
// cout<<li<<' '<<ri<<endl;
update(1,1,n,1,li,ri-1);
}
else
dfs(v,rt);
}
if(dlt[rt]==0)
lstk--;
} void makeTree()
{
build(1,1,n);
memset(vis,0,sizeof(vis));
memset(dlt,0,sizeof(dlt));
for(int i=1;i<=n;i++)
if(vis[i]==0)
dfs(i,-1);
} int q;
int rib[M];
ll pre[M]; void solve(int qli,int qri)
{
ll ans;
int i,j;
ll cnt1,cnt2;
int li=qli-1,ri=qri,mid;
while(li<ri-1)
{
mid=(li+ri)>>1;
if(rib[mid]>=qri)
ri=mid;
else li=mid;
}
cnt1=li-qli+1; cnt2=qri-li;
ans=pre[li]-pre[qli-1]-(2*qli-3+cnt1)*cnt1/2+(1+cnt2)*cnt2/2;
printf("%I64d\n",ans);
} int main()
{
int a,b;
init();
scanf("%d%d",&n,&m);
memset(dg,0,sizeof(dg));
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
addedge(a,b);
addedge(b,a);
dg[a]++,dg[b]++;
}
makeTree();
for(int i=1;i<=n;i++)
rib[i]=query(1,1,n,i,i);
pre[0]=0;
for(int i=1;i<=n;i++)
pre[i]=pre[i-1]+rib[i];
// for(int i=1;i<=n;i++)
// cout<<rib[i]<<' ';
// cout<<endl;
scanf("%d",&q);
for(int i=1;i<=q;i++)
{
scanf("%d%d",&a,&b);
solve(a,b);
}
return 0;
}

  

  

Codeforces Round #453 (Div. 1) 901C C. Bipartite Segments的更多相关文章

  1. Codeforces Round #453 (Div. 1)

    Codeforces Round #453 (Div. 1) A. Hashing Trees 题目描述:给出一棵树的高度和每一层的节点数,问是否有两棵树都满足这个条件,若有,则输出这两棵树,否则输出 ...

  2. Codeforces Round #453 (Div. 1) D. Weighting a Tree(构造)

    题意 一个 \(n\) 个点 \(m\) 条边的无向连通图中每个点都有一个权值,现在要求给每条边定一个权值,满足每个点的权值等于所有相连的边权之和,权值可负. 题解 如果图是一棵树,那么方案就是唯一的 ...

  3. 【做题】Codeforces Round #453 (Div. 1) D. Weighting a Tree——拆环

    前言:结论题似乎是我的硬伤…… 题意是给你一个无向图,已知连接到每一个点的边的权值和(为整数,且属于区间[-n,n]),需要求出每条边权值的一个合法解(都要是在区间[-2*n^2,2*n^2]内的整数 ...

  4. Codeforces Round #453 ( Div. 2) Editorial ABCD

    A. Visiting a Friend time limit per test 1 second memory limit per test 256 megabytes input standard ...

  5. Codeforces Round #453 Div. 2 A B C D (暂时)

    // 从大作业和实验报告中爬出来水一发 // 补题...还是得排在写完实验报告之后... A. Visiting a Friend 题意 给定若干段行车区间,问能否从起点到终点 思路 扫描一遍,维护最 ...

  6. 【Codeforces Round #453 (Div. 2) A】 Visiting a Friend

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 维护最右端的端点就好. [代码] #include <bits/stdc++.h> using namespace st ...

  7. 【Codeforces Round #453 (Div. 2) B】Coloring a Tree

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 从根节点开始. 显然它是什么颜色.就要改成对应的颜色.(如果上面已经有某个点传了值就不用改 然后往下传值. [代码] #includ ...

  8. 【Codeforces Round #453 (Div. 2) C】 Hashing Trees

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 显然只有当a[i]和a[i-1]都大于1的时候才会有不同的情况. a[i] >= a[i-1] 且a[i-1]>=2 则 ...

  9. Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树扫描线

    D. Vika and Segments 题目连接: http://www.codeforces.com/contest/610/problem/D Description Vika has an i ...

随机推荐

  1. POJ 1860 汇率 SPFA

    题意 有多种汇币,汇币之间可以交换,这需要手续费,当你用100A币交换B币时,A到B的汇率是29.75,手续费是0.39,那么你可以得到(100 - 0.39) * 29.75 = 2963.3975 ...

  2. 逆向知识第九讲,switch case语句在汇编中表达的方式

    一丶Switch Case语句在汇编中的第一种表达方式 (引导性跳转表) 第一种表达方式生成条件: case 个数偏少,那么汇编中将会生成引导性的跳转表,会做出 if else的情况(类似,但还是能分 ...

  3. Ocelot + Consul的demo

    参考大佬的博客写的:https://www.cnblogs.com/alan-lin/p/9126155.html:也可以参考这篇博客:https://www.cnblogs.com/axzxs200 ...

  4. MyEclipse eclipse console edit packageExplorer 颜色设置、个性化、常用设置

    下列教程的图片是在 myeclipse2014 破解版上进行,会有些许不同,仅供参考! 1 编辑区颜色设置 主题设置 豆沙绿设置 RGB 203 233 207 2 console 3主题选择 4 去 ...

  5. oracle解锁oracle默认用户scott

    oracle中存在一个默认的用户scott,密码为tiger,当在安装oracle时,若未给该账户解锁,则登录该用户时, 会提示被锁定. 如何通过sqlplus命令为scott解锁: 1.C:> ...

  6. ORACLE和SQL查询库数据量

    ORACLE根据账号查询每张表数据量: select t.table_name,t.num_rows from user_tables t ORDER BY NUM_ROWS DESC; SQL SE ...

  7. Spring中事务的传播行为,7种事务的传播行为,数据库事务的隔离级别

    Propagation.REQUIRED 代表当前方法支持当前的事务,且与调用者处于同一事务上下文中,回滚统一回滚(如果当前方法是被其他方法调用的时候,且调用者本身即有事务),如果没有事务,则自己新建 ...

  8. OpenCV入门学习资料汇总

    OpenCV学习文档资料 OpenCV学习:1)OpenCV中文网站——http://wiki.opencv.org.cn/index.php/%E9%A6%96%E9%A1%B5 2)python实 ...

  9. Django的ORM获取单表数据的三种方法

    前言主题是从数据库取数据,把数据展现到前端客户端 一共有三种方法如下: 1,以对象的方法: 2,以字典的方法: 3,以元组的方法: 以对象的方法 说明:获取的是QuerySet类型,输出的是每个元素都 ...

  10. Linux特殊权限及ACL权限

    一.SetUID与SGID 只能用于二进制程序,脚本不能设置 执行者需要有该二进制程序的x权限 执行具有SUID权限的二进制程序,那么执行者将具有该二进制程序所有者的权限. 举例来说,/etc/pas ...