JZOJ.5305【NOIP2017模拟8.18】C

Description

Input

Output

Sample Input

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

Sample Output

2
2
2
4
4
1 

Data Constraint

Hint

题意有点问题,实际上简单路径这里指的是不经过重复边的路径。

这题Tarjan缩点,然后LCA统计两点间环的个数k,答案就是2k个路径。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cmath>
  5 #define M 600010
  6 #define N 100010
  7 #define mo 100000007
  8 using namespace std;
  9 int head[N],next[M],to[M],n,m,belong[N],dfn[N],low[N],zhan[N],sigh[N],num,ti,q,top,deep[N],visit[N],up[N][30];
 10 long long ans,sum[N];
 11 void add(int u,int v){
 12     num++;
 13     next[num]=head[u];
 14     to[num]=v;
 15     head[u]=num;
 16     num++;
 17     next[num]=head[v];
 18     to[num]=u;
 19     head[v]=num;
 20 }
 21 void Tarjan(int x,int fa){
 22     zhan[++top]=x;
 23     ti++;
 24     dfn[x]=ti;
 25     low[x]=ti;
 26     for (int v,i=head[x];i;i=next[i]){
 27         v=to[i];
 28         if (v==fa) continue;
 29         if (!dfn[v]){
 30             Tarjan(v,x);
 31             low[x]=min(low[x],low[v]);
 32         } else low[x]=min(low[x],dfn[v]);
 33     }
 34     if (dfn[x]==low[x]){
 35         do{    sigh[x]++;
 36             belong[zhan[top]]=x;
 37             top--;
 38         }while(zhan[top+1]!=x);
 39         sigh[x]--;
 40     }
 41 }
 42 void DFS(int x,int fa){
 43     if (x==1) up[x][0]=x;
 44     else up[x][0]=fa;
 45     for (int i=1;i<=25;i++)
 46         up[x][i]=up[up[x][i-1]][i-1];
 47     deep[x]=deep[fa]+1;
 48     if (sigh[x]) sum[x]=sum[fa]+1;
 49     else sum[x]=sum[fa];
 50     for (int v,i=head[x];i;i=next[i]){
 51         v=to[i];
 52         if (belong[v]==belong[fa]) continue;
 53         if (belong[v]!=belong[x])
 54             DFS(v,x);
 55     }
 56 }
 57 long long kuai(long long a,long long b){
 58     long long ans=1;
 59     long long mi=b;
 60     long long qwq=a;
 61     while (mi){
 62         if (mi&1) ans=ans*qwq%mo;
 63         qwq=qwq*qwq%mo;
 64         mi>>=1;
 65     }
 66     return ans;
 67 }
 68 int lca(int u,int v){
 69     if (deep[u]<deep[v]) swap(u,v);
 70     for (int i=25;i>=0;i--)
 71         if (deep[v]<=deep[up[u][i]])
 72             u=up[u][i];
 73     if (u==v) return u;
 74     for (int i=25;i>=0;i--)
 75         if (up[u][i]!=up[v][i])
 76             u=up[u][i],v=up[v][i];
 77     return up[u][0];
 78 }
 79 int main(){
 80     scanf("%d%d",&n,&m);
 81     num=0;
 82     for (int i=1,u,v;i<=m;i++){
 83         scanf("%d%d",&u,&v);
 84         add(u,v);
 85     }
 86     for (int i=1;i<=n;i++)
 87         sigh[i]=0;
 88     ti=0;
 89     top=0;
 90     Tarjan(1,0);
 91     for (int i=1;i<=n;i++){
 92         if (belong[i]!=i)
 93             for (int v,j=head[i];j;j=next[j]){
 94                 v=to[j];
 95                 if (belong[v]!=belong[i])
 96                     add(v,belong[i]);
 97             }
 98     }
 99     sum[0]=0;
100     deep[0]=0;
101     DFS(1,0);
102     scanf("%d",&q);
103     for (int i=1,u,v,father;i<=q;i++){
104         ans=0;
105         scanf("%d%d",&u,&v);
106         if (u==v) if (sigh[belong[u]]) {printf("1\n");continue;}else {printf("0\n");continue;}
107         u=belong[u],v=belong[v];
108         if (deep[u]<deep[v]) swap(u,v);
109         father=lca(u,v);
110         ans=sum[u]+sum[v]-2*sum[father]+(sigh[father]?1:0);
111         printf("%lld\n",kuai(2,ans)%mo);
112     }
113     return 0;
114 }

神奇的代码

时间: 2024-10-24 18:55:27

JZOJ.5305【NOIP2017模拟8.18】C的相关文章

JZOJ.5307【NOIP2017模拟8.18】偷窃

Description Input Output Sample Input 5 5 1 4 0 5 2 2 1 2 0 1 0 2 3 4 4 0 3 0 3 1 1 2 2 1 1 Sample Output 9 Data Constraint Hint 本题直接做比较麻烦,加上金砖可移动. 这题就是要求我们找出一种摆放方式,三视图与之前一样且用得金块数最少. 我们可以重新构造. 对于俯视图,它提供的信息就是我们要在哪里放金砖,哪里不能放金砖. 对于正视图和侧视图,它提供的信息就是某一行或某一

JZOJ.5306【NOIP2017模拟8.18】棋盘游戏

Description 这个游戏上在一个无限大的棋盘上, 棋盘上只有一颗棋子在位置(x,y)(x,y>=0)棋盘的左下角是(0,0)Amphetamine每次都是第一个移动棋子,然后Amphetamine与Alphago轮流移动.每一轮可以做以下三种中的一种操作: 1)在同一行,将棋子从当前位置向左移动任意格:2)在同一列,将棋子从当前位置向下移动任意格: 3)将棋子从当前位置向下移动k格再向左移动k格(k为任意正整数,且要满足移动后的棋子仍然在棋盘上) 第一个不能在棋盘上移动的人比赛算输(因为

Cisco PT模拟实验(18) 路由器DHCP服务器及中继配置

Cisco PT模拟实验(18) 路由器DHCP服务器及中继配置 实验目的: 掌握路由器DHCP服务器的配置方法 掌握DHCP中继代理的配置方法 掌握DHCP协议及其中继的原理及实现过程 实验背景: 随着公司网络规模不断扩大,公司内办公电脑越来越多,原先的固定IP接入方案已经不再适用于复杂多变的网络环境.为了简化网管的管理维护工作,公司决定采用将路由器配置为DHCP服务器,使得企业网内部主机接入后自动获取IP地址,从而实现主机之间的相互通信. 技术原理: DHCP(Dynamic Host Co

JZOJ.5331【NOIP2017模拟8.23】壕游戏

Description Input Output Sample Input 6 8 2 2 4 5  1 2 4 0 2 1 3 5 0 2 3 4 1 5 1 2 5 1 0 1 4 6 4 2 2 5 6 0 4 2 1 5 5 9 2 2 6 4 5 2 Sample Output 16 Data Constraint Hint 类似于一种可撤销的贪心,不难想到这是费用流的模型. 考虑到我们实际会用到的边比实际的边少很多,我们可以动态建边,以减少空间的使用,即当流过了一条边之后再建立第二次

JZOJ.5274【NOIP2017模拟8.14】数组

Description Input Output Sample Input 输入样例1: 3 2 7 5 4 2 输入样例2: 5 3 1 5 4 3 5 5 Sample Output 输出样例1: 999999732 输出样例2: 0 Data Constraint 这个题要求乘积最小,显然我们希望乘积是负数是最好的,然后就是让这个负数的绝对值尽可能的大. 对于一堆数相乘,绝对值最小的对这个结果影响是最大的,所以我们就每次让绝对值最小的,如果是正数就加上x,负数就减去x,用个优先队列维护绝对

JZOJ.5281【NOIP2017模拟8.15】钦点

Description Input Output Sample Input 4 4 2 a a b b a a b b c c d d c c d d 1 1 3 3 2 2 3 1 1 3 2 2 Sample Output d d c c  d d c c  b b a a  b b a a  Data Constraint 本题时限4s. 很明显这是一道模拟题,朴素算法O(nmq)看似过得去,实际上字符串的操作是很慢的,同样对字符串赋值10w次比对数组元素赋值10w次要慢3倍以上. 实际上

JZOJ.5287【NOIP2017模拟8.16】最短路

Description Input Output Sample Input 9 10 2 1 2 1 1 4 1 3 4 1 2 3 1 3 7 1 7 8 2 7 9 2 1 5 3 1 6 4 5 6 1 1 9 5 7  Sample Output 5 6 Data Constraint 容易发现这是一张仙人掌图(每条边最多属于一个环的无向连通图) 仙人掌图求最短路的常用处理方法是将它变成一棵树,原图里为环的点更改为该环上的点都指向该环的某个点A,然后边长就是该点到点A的最短路径. 再预处

JZOJ.5329【NOIP2017模拟8.22】时间机器

Description Input Output Sample Input 3 2 2 1 4 2 3 5 1 1 4 2 2 5 1 3 2 1 3 1 2 4 1 3 5 1 1 3 2 2 5 1 2 2 1 2 2 1 2 1 1 2 1 1 2 2   Sample Output Yes No Yes Data Constraint Hint 很明显这是要让我们匹配,很容易想到可以二分图匹配,但是又有数量,于是我们可以网络流,但是n还是巨大,使得我们不得不想想其他办法. 我们的期望搭配

JZOJ.5286【NOIP2017模拟8.16】花花的森林

Description Input Output Sample Input 3 1 2 3 1 2 1 3 2 1 Sample Output 6 9 6 Data Constraint Hint 题目大意就是要求删边和计算直径. 很明显每次删边后两边BFS计算直径必会超时,但我们可以通过lca和预处理节点到根节点的距离来快速计算,但删边后lca很可能有所变化,重新预处理lca的信息又太慢了. 我们可以试着逆向. 即正着删边看成反着添边. 这样子我们可以发现是等效的. 一开始每棵树的直径就是该点