正睿提高组2017模拟题二T2

不会线性的,但是群里有个大神,发现用可以用80分的复杂度写出100分的效果,于是。。。。

考虑每次加入一条边,我们用f[x][j]表示加入第i条边后,当前的并查集x中,第j个点的父亲。那么如何加呢?假设当前第i条边的两端点为u和v,如果第x个并查集中u和v联通那么很明显,它不可以再加到这个并查集中(每个并查集维护的就是一个极大森林),然后就往后找,直到能找到一个x使得其中u和v是不连通的为止(肯定能找到,因为如果已有的都已经连通,说明前x个极大森林中都无法删去这条边,所以再构建一个新的并查集就好了)然后将其中的u和v设为联通的。最后你会发现那条边被添加进了哪个并查集,它的答案就是并查集的标号。

但是我们不可能在添加边的时候一个个找并查集吧,又可以发现如果第x个并查集中u和v是联通的,那么1~x-1个并查集中u和v也一定是联通的(构建的方法所致),所以根据这个,我们就每次二分一下找到标号最小的可以将当前边添加进去的并查集。

然后又有一个问题了,如果这么开的话空间是f[m][n]的,这样也不行。所以我们还要用deg[i]来记录每个点的连接的边数,假设deg[i]=x,那么可以发现,i这个点只有可能在前x个并查集中与其他点联通(要不然边不够),又因为有m条边所以deg[i]的总和为2m,所以开上2m的空间就好了。

对,然后又有一个问题了,怎么开呢,每一维的第二维大小都不同啊(这个我真的不会啊,发现别人是用指针的,于是看了老半天别人的代码,又去研究了怎么用指针。。。)

于是乎推荐一篇博客,里面有写怎么用数组指针:http://www.cnblogs.com/ggjucheng/archive/2011/12/13/2286391.html

对,就这样了,代码的解释之后再写吧。。。

不过按照复杂度这只有80分!!!(不知道为什么过了)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#define maxn 1000009
using namespace std;
int d[maxn],a[maxn*2],*f[maxn],*to=a,n,m,u[maxn],v[maxn];
typedef long long ll;
inline int read()
{
  char ch; int ex=0;
  while ((ch<‘0‘)||(ch>‘9‘)) ch=getchar();
  while ((ch>=‘0‘)&&(ch<=‘9‘))
  {
    ex=ex*10+ch-‘0‘;
    ch=getchar();
  }
  return ex;
}
int getf(int dep,int x)
{
  int now=x,k;
  while (*(f[now]+dep)!=now) now=*(f[now]+dep);
  while (*(f[x]+dep)!=now) k=*(f[x]+dep),*(f[x]+dep)=now,x=k;
  return now;
}
int main()
{
  n=read();m=read();
  for (int i=1;i<=m;i++) u[i]=read(),v[i]=read(),d[u[i]]++,d[v[i]]++;
  for (int i=1;i<=n;i++)
  {
      f[i]=to; to+=d[i];
      for (int j=1;j<=d[i];j++) *(f[i]+j)=i;
      d[i]=1;
  }
  for (int i=1;i<=m;i++)
  {
      int l=1,r=min(d[u[i]],d[v[i]]),mid,ans=0;
      d[u[i]]++;d[v[i]]++;
      while (l<=r)
      {
        mid=(l+r)>>1;
        if (getf(mid,u[i])==getf(mid,v[i])) l=mid+1;
      else
      {
        ans=mid;
        r=mid-1;
      }
    }
    *(f[getf(ans,u[i])]+ans)=getf(ans,v[i]);
    printf("%d\n",ans);
  }
  return 0;
}
时间: 2024-11-05 14:52:38

正睿提高组2017模拟题二T2的相关文章

正睿提高组2017模拟题三T1

听了很久又看了很久别人的程序才听懂,于是乎记录一下防止以后忘记. 好啦,假设当前 l-1=5,r=7;那如果学习过树状数组的话就知道题目中的操作如果转换为二进制的话 对于l-1来说他的二进制是101,所以会被加上-1的位置是101和100,r的二进制是111,所以会被加上1的位置是111,110,100 所以可以发现最后更新的位置是l-1的二进制的1的个数+r的二进制的1的个数-2*l-1和r都会更新的位置. 而l-1和r减1都会更新的位置的个数是它们两个二进制的最长公共前缀的1的个数(当然,前

2017.12.02【NOIP提高组】模拟赛A组

2017.12.02[NOIP提高组]模拟赛A组 T1 3555[GDKOI2014模拟]树的直径 T2 3542[清华集训2014]冒泡排序 T3 3486[NOIP2013模拟联考10]道路改建(rebuild) T1 树直径的一个性质,两棵树合并,形成新的树的直径的两个端点为原树中的四个端点之二. 可以用反证法证明.用此性质本题就变成了lca裸题了 Code #include<cstdio> #include<cstring> #include<cmath> #i

2017.11.25【NOIP提高组】模拟赛A组

2017.11.25[NOIP提高组]模拟赛A组 T1 3467. [NOIP2013模拟联考7]最长上升子序列(lis) T2 3468. [NOIP2013模拟联考7]OSU!(osu) T3 3472. [NOIP2013模拟联考8]匹配(match) T1 有转移方程f[i]=max{f[j]}+1,a[j]<a[i] 可以用线段树+离散化维护这个方程,因为涉及以往状态可以用主席树维护 打太丑爆空间了 Code 1 #include<cstdio> 2 #include<c

2017.12.09【NOIP提高组】模拟赛A组

2017.12.09[NOIP提高组]模拟赛A组 T1 3489. [NOIP2013模拟联考11]数列的GCD(gcd) T2 3500.[NOIP2013模拟联考15]物语(monogatari) T3 3501.[NOIP2013模拟联考15]消息传递(news) 吐槽:这次的题好像有点水啊,但最简单的第二题都给打挂啦!!(数组开小了) T1 本套题中最难的题.考虑dp 设f[i]是b[1],b[2]...b[N]的最大公约数的数目,g[i]是b[1],b[2]...b[N]的公约数的数目

NOIP 2008提高组第三题题解by rLq

啊啊啊啊啊啊今天已经星期三了吗 那么,来一波题解吧 本题地址http://www.luogu.org/problem/show?pid=1006 传纸条 题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是,他们可以通过传纸条来进行交流.纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n).从小渊

NOIP2008提高组(前三题) -SilverN

此处为前三题,第四题将单独发布 火柴棒等式 题目描述 给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法如图所示: 注意: 加号与等号各自需要两根火柴棍 如果A≠B,则A+B=C与B+A=C视为不同的等式(A.B.C>=0) n根火柴棍必须全部用上 输入输出格式 输入格式: 输入文件matches.in共一行,又一个整数n(n<=24). 输出格式: 输出文件matches.out共一行,

9.22 正睿提高4

目录 2018.9.22 正睿提高5 A 数组计数(DP) B 旅行(思路) C 进化(思路 二进制拆分) 考试代码 B C 2018.9.22 正睿提高5 时间:3.5h 期望得分:100+80+30 实际得分:100+80+30 比赛链接 T2一直以为类似某道虚树题(SDOI2015)..到最后只想写暴力(写了暴力也该想到了啊 但是已经在划水了). A 数组计数(DP) 题目链接 DP.前缀和优化一下就行了. 刚开始滚动数组又少清空了mmp.. #include <cstdio> #inc

2017.07.11【NOIP提高组】模拟赛B组

Summary 今天的比赛打得还不错,第一题被同桌灌输的贪心,纯模拟洗脑了,然后steal的看了一下,发现怎么也对不了,一直在检查.最后10分钟才找出反例,推出动态规划方程,没有想到怎么转移,比赛就结束了.第二题题意理解错误了,但是还是拿到了充满希望的10分,第三题看到题目就直接上了线段树,我想没几个人能像我一样5分钟想完并打完这道题了.贪心一定要看到反例,不能盲目去做,否则浪费了时间,更让心情愈来愈不甘. Problem T1 解题 题目大意 奶牛有P (P≤300) 道题目要做.他们的月薪是

2017.07.10【NOIP提高组】模拟赛B组

Summary 今天题目总体不是难,但是分数很低,只有100+10+30,其中第二题还是以前做过的,第一题设计数论,而且以前做过同一个类型的题目,比赛推了很长时间.第三题时以前做过的原题,是贪心没学好啊!方法也不够周到,数据看得不仔细. Problem T1 可见点数 题目大意 我更改了一下,但是求的东西是一样的.已知有n*n个人在一个n*n网络的格点上,有个人在(1,1)的位置,问他能看到多少个人的脸,不包括自己. 想法 已知一个定理,说得笼统一点,(x,y)和(x+a,y+b)点连一条边,其