码迷,mamicode.com
首页 > 其他好文 > 详细

重组公司

时间:2017-02-05 21:51:17      阅读:267      评论:0      收藏:0      [点我收藏+]

标签:while   targe   inline   技术   ace   输出   text   需要   ret   

 
题目来源: CodeForces
基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
 

有n个人在公司里面工作。员工从1到n编号。每一个人属于一个部门。刚开始每一个人在自己的部门负责自己的项目,这样的话公司里面就有n个部门。

然而,公司内部出现了危机,需要合并一些部门,以提高工作效率。team(person) 表示person这个人所在的部门。有以下两种合并操作:

1.    合并 team(x) 和 team(y)。 x和 y (1≤x,y≤n)是员工编号。如果team(x) 和 team(y)是同一个部门,那么就不操作。

2.    合并team(x),team(x+1),...,team(y),x 和 y (1≤x≤y≤n)是员工编号。

有一些查询操作,查询员工x 和 y (1≤x,y≤n)是否属于同一部门。

Input
单组测试数据。
第一行有两个整数n 和 q (1≤n≤200000, 1≤q≤500000)表示员工的数目和操作数目。
接下来q行,每行的格式是type x y。type∈{1,2,3}。如果type=1 或者 type=2,那么表示第一种或者第二种合并操作。如果type=3,表示查询员工x和y是否属于同一部门。
Output
对于第三种查询,如果属于同一部门输出YES,否则输出NO。
Input示例
样例输入1
8 6
3 2 5
1 2 5
3 2 5
2 4 7
2 1 2
3 1 7
Output示例
样例输出1
NO
YES
YES
主要看操作2
开一个数组near[],near[i]=j表示从i往前,与i不同的第一个部门是j
然后i从y倒着枚举到x,i每次跳到near[i]
一、
优化1:读入优化
优化2:输出用puts
优化3:函数前+inline
加了这3个优化刚刚卡过去,2个点都900多ms了
技术分享
#include<cstdio>
#define N 200001 
using namespace std;
int n,m;
int fa[N],near[N];
int type,x,y;
inline int find(int i) {return fa[i]==i ? fa[i]:fa[i]=find(fa[i]);}
inline int init()
{
    int x=0;char c=getchar();
    while(c<0||c>9) c=getchar();
    while(c>=0&&c<=9) {x=x*10+c-0;c=getchar();}
    return x;
}
inline void unionn()
{
    fa[find(x)]=find(y);
}

 inline void merge()
  {
   int t,i=y;
   while(i>=x&&(t=near[i])>=x)
   {
      fa[find(t)]=fa[find(i)];
      near[i]=near[t];
      i=t;
   }
  }

int main()
{
    n=init();m=init();
    for(int i=1;i<=n;i++)
    {
        fa[i]=i;near[i]=i-1;
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&type);
        x=init();y=init();
        if(type==1) unionn();
        else if(type==2) merge();
        else
        {
            int r1=find(x),r2=find(y);
            if(r1==r2) puts("YES\n");
            else puts("NO\n");
        }
    }    
} 

二、

事实证明读入一个数字用读入优化也比scanf快

我真的只是把type的读入由scanf改成了也用读入优化

技术分享


#include<cstdio>
#define N 200001 
using namespace std;
int n,m;
int fa[N],near[N];
int type,x,y;
inline int find(int i) {return fa[i]==i ? fa[i]:fa[i]=find(fa[i]);}
inline int init()
{
    int x=0;char c=getchar();
    while(c<0||c>9) c=getchar();
    while(c>=0&&c<=9) {x=x*10+c-0;c=getchar();}
    return x;
}
inline void unionn()
{
    fa[find(x)]=find(y);
}
inline void merge()
{
    int t,i=y;
    while(i>=x&&(t=near[i])>=x)
    {
        fa[find(t)]=fa[find(i)];
        near[i]=near[t];    
        i=t;
    }
} 
int main()
{
    n=init();m=init();
    for(int i=1;i<=n;i++)
    {
        fa[i]=i;near[i]=i-1;
    }
    for(int i=1;i<=m;i++)
    {
        type=init();x=init();y=init();
        if(type==1) unionn();
        else if(type==2) merge();
        else
        {
            if(find(x)==find(y)) puts("YES\n");
            else puts("NO\n");
        }
    }    
} 

 

 

重组公司

标签:while   targe   inline   技术   ace   输出   text   需要   ret   

原文地址:http://www.cnblogs.com/TheRoadToTheGold/p/6368548.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!