• 【GDOI2016模拟3.11】历史


    Description
    这里写图片描述

    Input
    这里写图片描述

    Output
    这里写图片描述

    Sample Input
    3 7
    R 0 1
    T 0 1 1
    K 1
    R 0 1
    T 0 1 1
    R 0 1
    T 0 2 1

    Sample Output
    Y
    N
    Y

    Data Constraint
    这里写图片描述
    .
    .
    .
    .
    .

    分析

    【简洁且能够处理询问也强制在线的情况】
    30%做法:暴力存下每次的并查集。复杂度O(nm)。
    70%做法:熟悉数据结构的同学应该很容易想到这个做法。这道题显然可以用可持久化并查集维护,用按秩合并套上一个可持久化线段树维护fa数组。复杂度O(nlog2n),由于数据有梯度,这个做法本地测试时给了70%的分数。但是要是又遇到跑得十分快的评测机,那我也是没办法了。/微笑/微笑/微笑
    100%做法:实际上我们并没有基于历史来修改fa数组,而只是基于历史查询,所以并不需要使用真正的可持久化。考虑套用上做法一,在并查集的边上存下这条边建立的时间。查询时查询一下到并查集的根这条路径的最小值即可知道两个结点连通的时间。复杂度O(nlogn),可以拿到100%的分数。
    .
    .

    注意:要读入优化!

    .
    .
    .
    .
    .

    程序:
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    int f[300001],sz[300001],year[300001],n,m,x,y,t,c=0,yr=0;
    char zf[3];
    bool bz=false;
    
    inline void read(int &x)
    {
        x=0;
        char c=getchar();
        while (c<'0' || c>'9') c=getchar();
        while (c>='0' && c<='9')
        {
            x=x*10+c-'0';
            c=getchar();
        } 
    }
    
    
    int find(int x, int t) 
    {
        while (x!=f[x]&&year[x]<=t) x=f[x];
        return x;
    }
    
    int main() 
    {
        read(n);
        read(m);
        for (int i=0;i<n;i++) 
        {
            f[i]=i; 
            sz[i]=1;
        }
        while (m--) 
        {
            scanf("%s",&zf);
            if (zf[0]=='K')
            { 
                read(c);
                bz=false; 
                continue;
            }
            if (zf[0]=='R')
            { 
                read(x);
                read(y);
                if (bz==true) 
                {
                    if ((x+=c)>=n) x-=n;
                    if ((y+=c)>=n) y-=n;
                }
                yr++;
                x=find(x,yr); 
                y=find(y,yr);
                if (x==y) continue;
                if (sz[x]<sz[y]) 
                {
                    f[x]=y;
                    sz[y]+=sz[x];
                    year[x]=yr;
                } else 
                {
                    f[y]=x;
                    sz[x]+=sz[y];
                    year[y]=yr;
                }
                continue;
            }
            if (zf[0]=='T')
            { 
                read(x);read(y);read(t);
                if (bz=((find(x,yr-t)==find(y,yr-t))||(find(x,yr)^find(y,yr)))) printf("N
    "); else printf("Y
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    vs运行代码版本不一致删除缓存
    spring framework 各版本源码下载地址
    类型初始值设定项引发异常
    datagridview 点击列标题排序
    软媒魔方u盘装系统
    sql中exists,not exists的用法
    java web第一个Servlet程序
    《ASP.NET 本质论》HttpApplication的处理管道 ,HttpMoudle,HttpHandler
    如何正确设置 Informix GLS 及 CSDK 语言环境
    Linux网络流量控制工具—Netem
  • 原文地址:https://www.cnblogs.com/YYC-0304/p/9499924.html
Copyright © 2020-2023  润新知