zoukankan      html  css  js  c++  java
  • Evanyou Blog 彩带

      题目传送门

      首先分析题目,数据范围特别大,500000组询问直接模拟肯定会超时,这里其实很容易可以想到用并查集。我们定义三个数组:fa[]表示每一个飞船的队首,front[]表示每一搜飞船到队首的距离,num[]表示以该飞船为队首的队伍中飞船的数量。每次M操作时就将x的队首的num值清空,并将fa值改变为y的队首,再将front值更新即可。询问时只要判断fa是否相等就可以了,不相等的话直接输出-1,否则输出abs(front[x]-front[y])-1。

      Code:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<iomanip>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int N=3e4+7;
    int n,fa[N],dis[N],cnt[N];
    inline int read()
    {
      char ch=getchar();int num=0;bool flag=false;
      while(ch<'0'||ch>'9'){if(ch=='-')flag=true;ch=getchar();}
      while(ch>='0'&&ch<='9'){num=num*10+ch-'0';ch=getchar();}
      return flag?-num:num;
    }
    inline int Abs(int x)
    {return x>0?x:-x;}
    inline int find(int x)
    {
      if(fa[x]==x)return x;
      int fx=find(fa[x]);
      dis[x]+=dis[fa[x]];
      return fa[x]=fx;
    }
    int main()
    {
      n=read();
      char s;int x,y;
      for(int i=1;i<=30000;i++)
        fa[i]=i,dis[i]=0,cnt[i]=1;
      for(int i=1;i<=n;i++){
        cin>>s;
        x=read();y=read();
        int fx=find(x),fy=find(y);
        if(s=='M'){
          if(fx==fy)continue;
          dis[fx]+=cnt[fy];
          fa[fx]=fy;
          cnt[fy]+=cnt[fx];
          cnt[fx]=0;}
        else{
          if(fx!=fy)printf("-1
    ");
          else printf("%d
    ",Abs(dis[x]-dis[y])-1);
        }
      }
      return 0;
    }

      

  • 相关阅读:
    计算任意两个日期的间隔天数
    题目标题: 排它平方数
    历届试题 剪格子
    历届试题 翻硬币
    C语言中%d,%o,%f,%e,%x的意义
    历届试题 买不到的数目
    九度 OJ1008 hdu 3790
    南洋理工 OJ 115 城市平乱 dijstra算法
    蓝桥杯 错误票据 原创代码+思路
    历届试题 连号区间数
  • 原文地址:https://www.cnblogs.com/cytus/p/8540129.html
Copyright © 2011-2022 走看看