地理课(geography)

题目描述

地理课上,老师给出了一个巨大的地图,由于世界日新月异,会有一些道路在某一时刻被删除,也会有一些道路在某一时刻被修建。这里的道路均为双向的。

老师认为,有一些城市被分在了一个连通块中可以相互到达,而有一些城市不能够相互到达。而他想知道,每个时刻所有连通块大小的乘积是多少?

wzy看到这个地图的时候就蒙了,还好那只上天的喵及时帮助了他。现在他把这个毒瘤的地图拿过来给你,想试试看你能不能求出来。由于答案可能很大,输出乘积mod109+7mod109+7即可。

输入

第一行两个数n,mn,m,表示有nn个点,mm个时刻。接下来mm行每行三个数,要么是1uv1uv,要么是2uv2uv,分别表示添加一条无向边和删除一条无向边。

输出

共mm,每行一个数表示连通块大小乘积mod1,000,000,007mod1,000,000,007

上面是每个时刻操作后的图。乘积分别为:

2*1*1*1=2,3*1*1=3,3*1*1=3,3*2=6,5,3*2=6

数据范围及约定

subtask1:30pts,n≤1,000,m≤2,000n≤1,000,m≤2,000

subtask2:20pts,满足没有删除操作。

subtask3:50pts,n,m≤100,000n,m≤100,000保证没有重边自环,不会删除不存在的边。

来源

noip2018南外-模拟


solution

好题好题

考虑离线,按时间建一棵线段树

把每一个边的编号加进线段树对应的区间中

我们现在希望得到每一个叶子节点的值

那么每次暴力求是不行了

我们记下每一层的边连接的并查集的根与大小

返回时把边拆开即可

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<algorithm>
  6. #include<cmath>
  7. #include<map>
  8. #include<vector>
  9. #define mod 1000000007
  10. #define maxn 100005
  11. #define ll long long
  12. using namespace std;
  13. int n,m,f[maxn],sz[maxn],t1,t2,op;
  14. ll now,ans[maxn],ny[maxn];
  15. struct node{
  16. int u,v,st,ed;
  17. }e[maxn];
  18. map<ll,int>ls;
  19. struct no{
  20. int l,r;
  21. vector<int>x;
  22. }tree[maxn*8];
  23. struct Node{
  24. int id,x,y,size;
  25. };
  26. vector<Node>p;
  27. void build(int k,int L,int R){
  28. tree[k].l=L,tree[k].r=R;
  29. if(L==R)return;
  30. int mid=L+R>>1;
  31. build(k*2,L,mid);build(k*2+1,mid+1,R);
  32. }
  33. void add(int k,int L,int R,int v){
  34. //cout<<k<<' '<<L<<' '<<R<<''<<endl;
  35. if(tree[k].l>=L&&tree[k].r<=R){
  36. tree[k].x.push_back(v);return;
  37. }
  38. int mid=tree[k].l+tree[k].r>>1;
  39. if(L<=mid)add(k*2,L,R,v);
  40. if(R>mid)add(k*2+1,L,R,v);
  41. }
  42. ll work(ll a,int num){
  43. ll an=1;
  44. while(num){
  45. if(num&1)an=an*a;
  46. a=a*a;a%=mod;an%=mod;num>>=1;
  47. }
  48. return an;
  49. }
  50. int getf(int k){
  51. if(f[k]==k)return k;
  52. return getf(f[k]);
  53. }
  54. void hb(int k){
  55. //cout<<"k: "<<k<<' '<<tree[k].l<<' '<<tree[k].r<<endl;
  56. for(int i=0;i<tree[k].x.size();i++){
  57. int t=tree[k].x[i];
  58. //cout<<t<<endl;
  59. int f1=getf(e[t].u),f2=getf(e[t].v);
  60. if(f1!=f2){
  61. now=now*ny[sz[f1]]%mod*ny[sz[f2]]%mod;
  62. now=now*(sz[f1]+sz[f2])%mod;
  63. if(sz[f1]<sz[f2]){
  64. p.push_back((Node){k,f1,f2,sz[f1]});
  65. f[f1]=f2;sz[f2]+=sz[f1];sz[f1]=0;
  66. }
  67. else {
  68. p.push_back((Node){k,f2,f1,sz[f2]});
  69. f[f2]=f1;sz[f1]+=sz[f2];sz[f2]=0;
  70. }
  71. }
  72. }
  73. }
  74. void turn(int k){
  75. int Size=p.size()-1;if(Size<0)return;
  76. //cout<<"Size "<<Size<<' '<<tree[k].l<<' '<<tree[k].r<<endl;
  77. for(int i=Size;p[i].id==k&&i>=0;i--){
  78. //cout<<p[i].x<<' '<<p[i].y<<' '<<sz[p[i].x]<<' '<<sz[p[i].y]<<endl;
  79. now=now*ny[sz[p[i].y]]%mod;
  80. f[p[i].x]=p[i].x;sz[p[i].x]=p[i].size;sz[p[i].y]-=sz[p[i].x];
  81. now=now*sz[p[i].x]%mod*sz[p[i].y]%mod;
  82. p.pop_back();
  83. }
  84. }
  85. void dfs(int k){
  86. hb(k);
  87. if(tree[k].l==tree[k].r){
  88. ans[tree[k].l]=now;turn(k);
  89. return;
  90. }
  91. dfs(k*2);dfs(k*2+1);
  92. turn(k);
  93. }
  94. int main()
  95. {
  96. cin>>n>>m;
  97. for(int i=1;i<=m;i++){
  98. scanf("%d%d%d",&op,&e[i].u,&e[i].v);
  99. if(e[i].u>e[i].v)swap(e[i].u,e[i].v);
  100. ll tmp=(ll)e[i].u*100000+e[i].v;
  101. if(op==1){ls[tmp]=i;e[i].st=i;}
  102. else {
  103. int la=ls[tmp];e[la].ed=i-1;
  104. //ls[tmp]=0;
  105. }
  106. }
  107. build(1,1,m);
  108. for(int i=1;i<=m;i++){
  109. if(e[i].ed==0)e[i].ed=m;
  110. if(e[i].st&&e[i].ed)add(1,e[i].st,e[i].ed,i);
  111. }
  112. for(int i=1;i<=n;i++)ny[i]=work(i,mod-2);
  113. for(int i=1;i<=n;i++)f[i]=i,sz[i]=1;
  114. now=1;dfs(1);
  115. for(int i=1;i<=m;i++)printf("%lld\n",ans[i]);
  116. return 0;
  117. }

地理课(geography)的更多相关文章

  1. [CSP-S模拟测试]:地理课(并查集+线段树分治)

    题目传送门(内部题146) 输入格式 从$geography.in$读入数据. 第一行两个数$n,m$,表示有$n$个点,$m$个时刻.接下来$m$行每行三个数,要么是$1\ u\ v$,要么是$2\ ...

  2. [考试反思]1112csp-s模拟测试111:二重

    还是AK场.考前信心赛? 而且T3的部分分还放反了所有80的都其实只有50. 总算在AK场真正AK了一次... 手感好,整场考试很顺利.要不是因为T3是原题可能就没这么好看了. 20minT1,50m ...

  3. Linux查看设置系统时区

    关于时区的概念,其实初中地理课已经涉及,很多人都多少了解一些,可能只是细节搞不太清楚.为什么会将地球分为不同时区呢?因为地球总是自西向东自转,东边总比西边先看到太阳,东边的时间也总比西边的早.东边时刻 ...

  4. ggplot2包--R可视化

    1.ggplot2发展历程 ggplot2是Hadley在爱荷华州立大学博士期间的作品,也是他博士论文的主题之一,实际上ggplot2还有个前身ggplot,但后来废弃了,某种程度上这也是Hadley ...

  5. linux概念之时间与时区

    http://www.cnblogs.com/liuyou/archive/2012/07/29/2614338.html Linux时间基准 以上我们了解了RTC(实时时钟.硬件时钟)和OS时钟(系 ...

  6. 文成小盆友python-num14 - web 前端基础 html ,css, JavaScript

    本部分主要内容 html - 基础 css - 基础 一.html 标签 html 文档标签树如下: head 部分 Meta(metadata information) 提供有关页面的元信息,例:页 ...

  7. [转]100个经典C语言程序(益智类问题)

    目录: 1.绘制余弦曲线 2.绘制余弦曲线和直线 3.绘制圆 4.歌星大奖赛 5.求最大数 6.高次方数的尾数 8.借书方案知多少 9.杨辉三角形 10.数制转换 11.打鱼还是晒网 12.抓交通肇事 ...

  8. 【算法】C语言趣味程序设计编程百例精解

    C语言趣味程序设计编程百例精解 C/C++语言经典.实用.趣味程序设计编程百例精解(1)  https://wenku.baidu.com/view/b9f683c08bd63186bcebbc3c. ...

  9. matplotlib等高线图-【老鱼学matplotlib】

    等高线图是在地理课中讲述山峰山谷时绘制的图形,在机器学习中也会被用在绘制梯度下降算法的图形中. 因为等高线的图有三个信息:x, y以及x,y所对应的高度值. 这个高度值的计算我们用一个函数来表述: # ...

随机推荐

  1. CUDA直方图实例=CPU+GPU(global)+GPU(shared)

    项目打包下载链接 顺便批判下CSDN上传坑爹现象,好多次都是到了95%或者99%就不动了.我……

  2. 博学谷-数据分析numpy

    import numpy as  np print np.version.version np.array([1,2,3,4]) np.arange(15) np.array(range(10)) = ...

  3. Linux运维企业架构项目实战系列

    Linux运维企业架构项目实战系列 项目实战1—LNMP的搭建.nginx的ssl加密.权限控制的实现 项目实战2—LVS.nginx实现负载均衡系列2.1 项目实战2.1—实现基于LVS负载均衡集群 ...

  4. 快速搭建FTP服务

    Linux下ftp服务可以通过搭建vsftpd服务来实现,以CentOS为例,首先查看系统中是否安装了vsftpd,可以通过执行命令 rpm -qa | grep vsftpd 来查看是否安装相应的包 ...

  5. 使用VUE开发

    <一>VUE的开发分两种,一种是直接在HTML文件中使用,一种是VUE文件的形式开发 1,首先我们先让 HTML 文件支持 VUE 的语法指令提示 2,File -> Setting ...

  6. MTCNN学习资源

    MTCNN pytorch版本的实现 TropComplique/mtcnn-pytorch https://github.com/TropComplique/mtcnn-pytorch MTCNN实 ...

  7. SpringBoot-Security-用户权限分配-项目搭建

    SpringBoot原则是约定优于配置,简化spring应用开发,去繁从简,产品级别的应用. SpringBoot有哪些优点1.快速创建独立运行的spring项目与主流框架集成 2.使用嵌入式的ser ...

  8. linux 服务器被植入ddgs、qW3xT.2挖矿病毒处理记录

    被入侵后的现象: 发现有qW3xT.2与ddgs两个异常进程,消耗了较高的cpu,kill掉后 过一会就会重新出现. kill 掉这两个异常进程后,过一段时间看到了如下进程: 首先在/etc/sysc ...

  9. 格雷码Gray Code详解

    格雷码简介 在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code),另外由于最大数与最小数之间也仅一位数不同,即“首尾相连”,因此又称循环码或反射码.格 ...

  10. RCP 主题切换

    第一步 编写css文件,放到项目目录下 第二步 添加切换主题扩展点 第三步 设置主题   public  void switchTheme(String themeID) {           Bu ...