#1629 : Graph

时间限制:4000ms
单点时限:4000ms
内存限制:256MB

描述

The country contains N cities numbered from 1 to N and M undirected roads connecting pairs of cities. There are some queries. Each query is represented by two numbers: L and R , meaning that all the cities whose number is between L and R(L and R are included) are safe, and other cities are not safe. We define city A can reach city B if and only if they are both safe and there exists a path from A to B that the cities on the path are all safe.

For each query, you need to figure out the number of pairs of cities that can reach each other under the condition given by the query.

输入

First line contains one number T which means the number of test cases.

For each test case, first line contains three numbers, above mentioned N , M and Q.

Next M lines, each line contains two integers: X, Y (X != Y) which means there is a road between city X and city Y (1 <= X,Y <= N).

Next Q lines, each line contains two numbers: L, R which indicates an query(1 <= L,R <= N, L <= R).

T <= 5, N , M <= 50000, Q <= 100000

输出

For each test case, output Q lines, each line contains the answer of the correspondent query.

样例输入
1
6 6 4
1 2
2 3
2 6
1 5
2 4
4 5
1 4
3 6
2 6
3 4
样例输出
6
1
10
0
分析:对于询问(L,R),可行的边(x,y)满足L<=x<=y<=R;
   那么分成两部分,满足L<=x的边与y<=R的边的交即可;
   于是把边拷贝两份分别排序求前缀交,可以离线用回滚莫队转移;
   维护答案用并查集即可;
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <bitset>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <cassert>
#include <ctime>
#define rep(i,m,n) for(i=m;i<=(int)n;i++)
#define inf 0x3f3f3f3f
#define mod 19260817
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define sys system("pause")
#define ls (rt<<1)
#define rs (rt<<1|1)
#define all(x) x.begin(),x.end()
const int maxn=1e5+;
const int N=2e5;
using namespace std;
ll gcd(ll p,ll q){return q==?p:gcd(q,p%q);}
ll qmul(ll p,ll q,ll mo){ll f=;while(q){if(q&)f=(f+p)%mo;p=(p+p)%mo;q>>=;}return f;}
ll qpow(ll p,ll q){ll f=;while(q){if(q&)f=f*p%mod;p=p*p%mod;q>>=;}return f;}
int n,m,k,t,q,num,bl[maxn],fa[maxn],sz[maxn],cnt[][maxn],tot,L[maxn],R[maxn];
ll ret,lst,ans[maxn];
struct node
{
int u,v,id;
bool operator<(const node&p)const
{
return bl[u]==bl[p.u]?v<p.v:bl[u]<bl[p.u];
}
}e[maxn],f[maxn],qu[maxn],tmp[maxn];
bool cmp1(node x,node y)
{
return x.u>y.u;
}
bool cmp2(node x,node y)
{
return x.v<y.v;
}
int find(int x){return fa[x]==x?x:find(fa[x]);}
void unite(int x,int y)
{
x=find(x),y=find(y);
if(x==y)return;
if(sz[x]>sz[y])swap(x,y);
fa[x]=y;
ret+=(ll)sz[y]*sz[x];
sz[y]+=sz[x];
}
void undo()
{
while(tot)
{
int x=tmp[tot].u,y=tmp[tot].v;
fa[x]=x;
sz[y]-=sz[x];
ret-=(ll)sz[y]*sz[x];
tot--;
}
}
int main(){
int i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&m,&q);
rep(i,,m)
{
int x,y;
scanf("%d%d",&x,&y);
if(x>y)swap(x,y);
e[i]=f[i]=node{x,y,i};
}
sort(e+,e+m+,cmp1);
sort(f+,f+m+,cmp2);
int pos=;
for(i=n;i>=;i--)
{
while(pos+<=m&&e[pos+].u>=i)pos++;
L[i]=pos;
}
pos=;
rep(i,,n)
{
while(pos+<=m&&f[pos+].v<=i)pos++;
R[i]=pos;
}
num=round(sqrt(m)+0.5);
rep(i,,m)bl[i]=(i-)/num+;
rep(i,,q)
{
int x,y;
scanf("%d%d",&x,&y);
if(x>y)swap(x,y);
qu[i]=node{L[x],R[y],i};
}
sort(qu+,qu+q+);
int l,r;
rep(i,,q)
{
if(i==||bl[qu[i].u]!=bl[qu[i-].u])
{
rep(j,,n)fa[j]=j,sz[j]=;
rep(j,,m)cnt[][j]=cnt[][j]=;
ret=tot=;
j=;
while(j<=m&&j<=bl[qu[i-].u]*num)++cnt[][e[j++].id];
l=j,r=;
}
while(r<=m&&r<=qu[i].v)
{
if(++cnt[][f[r].id]==&&cnt[][f[r].id])
{
unite(f[r].u,f[r].v);
}
r++;
}
lst=ret;
while(l<=m&&l<=qu[i].u)
{
if(++cnt[][e[l].id]==&&cnt[][e[l].id])
{
int x=find(e[l].u),y=find(e[l].v);
if(x!=y)
{
if(sz[x]>sz[y])swap(x,y);
tmp[++tot]=node{x,y,};
unite(x,y);
}
}
l++;
}
while(l>j)
{
--cnt[][e[--l].id];
}
ans[qu[i].id]=ret;
undo();
ret=lst;
}
rep(i,,q)printf("%lld\n",ans[i]);
}
return ;
}
/*
1
3 3 6
1 2
2 3
3 1
1 1
2 2
3 3
1 2
2 3
1 3
*/

2017北京ICPC C题 Graph的更多相关文章

  1. 2017北京国庆刷题Day1 afternoon

    期望得分:100+100+100=300 实际得分:100+100+100=300 T1 一道图论好题(graph) Time Limit:1000ms   Memory Limit:128MB 题目 ...

  2. 2017北京国庆刷题Day7 morning

    期望得分:100+0+100=200 实际得分:100+20+0=120 离散化搞搞 #include<cstdio> #include<iostream> #include& ...

  3. 2017北京国庆刷题Day5 afternoon

    期望得分:100+60+100=260 实际得分:0+60+40=100 设图中有m个环,每个环有si条边,有k条边不在环中 ans= (2^s1 -2)*( 2^s2 -2)* (2^s3 -2)… ...

  4. 2017北京国庆刷题Day3 morning

    期望得分:100+60+0=160 实际得分:100+30+0=130 考场上用的哈希 #include<cstdio> #include<cstring> #include& ...

  5. 2017北京国庆刷题Day2 afternoon

    期望得分:100+100+50=250 实际得分:100+70+50=220 T1 最大值(max) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK有一 ...

  6. 2017北京国庆刷题Day2 morning

    期望得分:100+100+40=240 实际得分:100+40+0=140 T1 一道图论神题(god) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK ...

  7. 2017北京国庆刷题Day4 morning

    期望得分:0+40+30=70 实际得分:0+10+10=20 题目修改:只能由0变1,只能用一次操作 大模拟 #include<cstdio> #include<cstring&g ...

  8. 2017北京国庆刷题Day5 morning

    期望得分:0+60+60=120 实际得分:0+30+60=90 令g=gcd(X11,X12,X13……) 则行列式可能为D的充要条件为g|D 1.g|D为必要条件: 由定义来算行列式的时候,每一项 ...

  9. 2017北京国庆刷题Day4 afternoon

    期望得分:100+100+0=200 实际得分:5+0+0=5 每加入一个数,x的因数位置++ 注意:根号x枚举时,如果x是完全平方数,根号x会重复累计2次,要减去 考场上没减,5分 /(ㄒoㄒ)/~ ...

随机推荐

  1. 为npm设置代理,解决网络问题

    为npm设置代理,解决网络问题 npm config set proxy=http://127.0.0.1:1080

  2. Spring中AOP的两种代理方式(Java动态代理和CGLIB代理-转载

    内容是摘抄的,不知最初的原作者,见谅 Java 动态代理.具体有如下四步骤: 通过实现 InvocationHandler 接口创建自己的调用处理器: 通过为 Proxy 类指定 ClassLoade ...

  3. 【WIP_S2】递归

    创建: 2018/01/14    递归  定义  自己召唤自己  通用形式  if (基本情况A的处理) {     ...     return 值A  } else if (基本情况B的处理) ...

  4. P2700逐个击破(并查集/树形dp)

    P2700 逐个击破 题目背景 三大战役的平津战场上,傅作义集团在以北平.天津为中心,东起唐山西至张家口的铁路线上摆起子一字长蛇阵,并企图在溃败时从海上南逃或向西逃窜.为了就地歼敌不让其逃走,老毛同志 ...

  5. CodeIgnitor 配置类的使用

    CI 的配置文件统一放在 application/config/ 目录下面,框架有一个默认的主配置文件 application/config/config.php.其部分内容如下: <?php ...

  6. 数据结构之单链表(C实现)

    list.h #ifndef LIST_H #define LIST_H #include <iostream> #include <stdio.h> #include < ...

  7. 数学+DP Codeforces Round #304 (Div. 2) D. Soldier and Number Game

    题目传送门 /* 题意:这题就是求b+1到a的因子个数和. 数学+DP:a[i]保存i的最小因子,dp[i] = dp[i/a[i]] +1;再来一个前缀和 */ /***************** ...

  8. 循环语言(for)

    循环语句: 给出初始条件,先判断是否满足循环条件,如果不满足条件则跳过for语句,如果满足则进入for语句循环,for语句内的代码执行完毕之后,将按照状态改变改变变量,然后判断是否符合循环条件,符合继 ...

  9. Echarts修改legend样式

    legend: { icon: 'rect', itemWidth: 20, itemHeight: 10, itemGap: 10}

  10. python自动化--mock、webservice及webdriver模拟手机浏览器

    一.mock实现 自定义一个类,用来模拟未完成部分的开发代码 class Say(): def say_hello(self): pass 自定义返回值 import unittest from un ...