【NOIP2016提高A组模拟9.15】Map
2016-09-18 18:53
316 查看
Description
Input
Output
所有询问的和Sample Input
4 4 21 2
2 3
3 2
3 4
1 2
1 4
Sample Output
14样例解释:
upd:保证原图连通。
“不相交路径”的定义为不存在相同的边。可以存在相同的点。重边视为不同的边。
对于样例:
原图有2个安全点对为(2,3),(3,2)
询问1答案为4,新增的安全点对为(1,2),(1,3),(2,1)(3,1)
询问2答案为10,新增的安全点对为(1,2),(1,3),(1,4),(2,1)(2,4),(3,1),(3,4),(4,1),(4,2),(4,3)
因此输出14
Data Constraint
n,q<=2∗105m<=4∗105
30%图为一棵树
Solution
新增的安全点对肯定在一个环上先考虑图为一棵树的情况
每次添加一条边,就会多一个环,环的大小可以通过LCA求出
答案增加相应数量就行了
那么对于一张图怎么办?Tarjan缩环,而缩环后的点的点权就是原来环的点的数量
设环上有k个点,每个点的点权为c[i]
那最后增加的答案就是
(∑ki=1c[i])2−∑ki=1c[i]2
Code
#include<cstdio> #include<cstring> #include<algorithm> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) #define N 200100 #define ll long long using namespace std; int n,m,tot=1,last[N*10],next[N*10],to[N*10],b[N*10][2],p[N],dfn[N],low[N],sy[N],f[N][18],deep ,bz ,bz2 ,totot=0; ll g[N][18],sn[N],g1[N][18]; void putin(int x,int y) { if (x==y) return; next[++tot]=last[x];last[x]=tot;to[tot]=y; next[++tot]=last[y];last[y]=tot;to[tot]=x; } void tarjan(int x,int fa) { low[x]=dfn[x]=++tot;p[++p[0]]=x;bz[x]=bz2[x]=1; for(int i=last[x];i;i=next[i]) { int y=to[i];if(i==(fa^1)) continue; if(!bz[y]) tarjan(y,i),low[x]=min(low[x],low[y]); else if(bz2[y]) low[x]=min(low[x],dfn[y]); } if(low[x]==dfn[x]) { totot++; for(;p[p[0]+1]!=x;p[0]--) { int k=p[p[0]];sy[k]=totot;sn[totot]++;bz2[k]=0; } } } ll sqr(ll x){return x*x;} void dfs(int x) { bz[x]=1; for(int i=last[x];i;i=next[i]) { int y=to[i]; if(bz[y]) continue; deep[y]=deep[x]+1;f[y][0]=x;g1[y][0]=sn[y];g[y][0]=sqr(sn[y]); dfs(y); } } ll lca(int x,int y) { ll a=0,b=0; fd(i,17,0) if(deep[f[x][i]]>=deep[y]) a+=g1[x][i],b+=g[x][i],x=f[x][i]; fd(i,17,0) if(deep[f[y][i]]>=deep[x]) a+=g1[y][i],b+=g[y][i],y=f[y][i]; fd(i,17,0) if(f[x][i]!=f[y][i]) a+=g1[x][i],b+=g[x][i],x=f[x][i],a+=g1[y][i],b+=g[y][i],y=f[y][i]; if(x!=y) a+=g1[x][0]+g1[y][0],b+=g[x][0]+g[y][0],x=f[x][0]; a+=g1[x][0],b+=g[x][0]; return sqr(a)-b; } int main() { int ac;scanf("%d %d %d",&n,&m,&ac); fo(i,1,n) sy[i]=i; fo(i,1,m) { int x,y;scanf("%d%d",&x,&y); putin(x,y);b[i][0]=x;b[i][1]=y; } tot=0;tarjan(1,-1); memset(last,0,sizeof(last));tot=1;memset(bz,0,sizeof(bz)); fo(i,1,m) putin(sy[b[i][0]],sy[b[i][1]]); deep[1]=1;g1[1][0]=sn[1];g[1][0]=sqr(sn[1]);dfs(1); ll ans=0; fo(j,1,17) fo(i,1,n) { f[i][j]=f[f[i][j-1]][j-1]; if(f[i][j]) g[i][j]=g[i][j-1]+g[f[i][j-1]][j-1],g1[i][j]=g1[i][j-1]+g1[f[i][j-1]][j-1]; } for(;ac;ac--) { int x,y;scanf("%d%d",&x,&y); ans+=lca(sy[x],sy[y]); } printf("%lld",ans); }
相关文章推荐
- 【JZOJ4784】【NOIP2016提高A组模拟9.15】Map
- 【NOIP2016提高A组模拟9.15】Map
- 【NOIP2016提高A组模拟9.15】Math
- 【JZOJ4782】【NOIP2016提高A组模拟9.15】Math
- 【NOIP2016提高A组模拟9.15】Math
- 【NOIP2016提高A组模拟9.15】Math
- 【NOIP2016提高A组模拟9.15】Osu
- NOIP2016提高A组模拟中秋节9.15总结
- 【NOIP2016提高A组模拟9.15】Osu
- 【NOIP2016提高A组模拟9.15】Osu
- 【NOIP2016提高A组模拟9.15】Math
- 【NOIP2016提高A组模拟9.15】Osu
- Math【NOIP2016提高A组模拟9.15】
- 【JZOJ4783】【NOIP2016提高A组模拟9.15】Osu
- 【NOIP2016提高A组模拟9.9】爬山
- [jzoj4603]【NOIP2016提高A组模拟7.15】颜料大乱斗
- 【JZOJ4787】【NOIP2016提高A组模拟9.17】数格子
- 就是乘法【NOIP2016提高A组模拟9.24】
- 【NOIP2016提高A组模拟8.14】传送带