• 历史


    3 历史(history.c/cpp/pas)
    3.1 题目描述
    历史学家小A正在研究一个奇怪的王国的历史。当前阶段的任务是研究该国的交通。
    根据这个奇怪的王国的史书记载,史书开始记载前这个王国有 n 个城市(城市从 0 开
    始标号),但所有城市之间都没有道路相连。
    每一年,在位的国王会修建一条 x 到 y 的双向道路,一条道路可能被修建多次,但不会
    修建起点和终点为同一个城市的道路。
    而在这之间,国王会计划进行若干次旅行。对于计划进行的一次旅行 st->ed,如果当
    时能完成这次旅行,而 t 年前不能完成这次旅行,那么国王会对之前的建设成果感到满意,
    否则他会很生气,并在下一次计划旅行前都让史官记录下错误的修建道路的信息,即把 x、
    y 记作(x+n-c) mod n,(y+n-c) mod n。
    当然在这些年中也发生了若干次国王的交替,初始国王的 c 值为 0,而每个国王的 c 值
    不一定相同,但在国王在位期间 c 值不会改变,新上位的国王开始处于不生气的状态。
    请根据史书帮助小 A 得出国王每次对于计划旅行是否满意,从而辅助小 A 能够研究该
    国的交通信息。
    3.2 输入格式
    第一行为两个整数 n,m,表示初始城市数和历史书记载的内容数。
    接下来 m 行,每行是以下三种格式之一:
    1 . K v :表示国王交替,新国王的 c 值为 v
    2 . R x y:表示史书上记载的是国王修建了 x 到 y 的双向道路,但注意这个记录的可
    能不是实际状况。
    3 . T st ed t:表示国王计划进行的一次 st->ed 的旅行,且比较的是 t 年前的情况(国
    NOIP 模拟试题 #5
    7
    王可能会和史书开始记载以前的情况比较),注意这个记录的肯定是实际情况。
    注意只有遇到 R 操作才会使年份的计数+1。
    3.3 输出格式
    输对于每个 T 的记录输出一行,如果此次计划旅行令国王满意,则输出 Y,否则输出 X。
    3.4 样例输入
    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
    3.5 样例输出
    Y
    N
    Y
    3 .6 数据范围与约定
    对于 30%的数据,保证 n<=1000 ,m<=3000。
    另 30%的数据满足没有发生国王的交替。
    NOIP 模拟试题 #5
    8
    对于 100%的数据,保证 n,m<=300000,0<=v,x,y,st,ed<n,0<=t<m。
    数据有梯度

     

    思路:

      在线处理,用并查集记录道路的连接情况,同时记录每条边的创建时间(这是为了找到t年前的道路连接情况)。

      注意查询时,有创建时间的限制。还有城市是从零开始的。

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    #define M 300009
    int n,m;
    int f[M],sum[M],yr[M];
    int anger,c,year,x,y,st,ed,t;
    int find(int x,int t)
    {
        while(x!=f[x] && yr[x]<=t) x=f[x];
        return x;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<=n;i++)    f[i]=i,sum[i]=1;
        char C;
        while(m--)
        {
            cin>>C;
            if(C=='K')
            {
                scanf("%d
    ",&c);
                anger=0;continue;
            }
            if(C=='R')
            {
                scanf("%d%d",&x,&y);
                if(anger)
                {
                    x+=c,y+=c;
                    x%=n,y%=n;                
                }
                year++;
                x=find(x,year);y=find(y,year);
                if(x == y) continue;
                if(sum[x] < sum[y]) {
                    f[x] = y;
                    sum[y] += sum[x];
                    yr[x] = year;
                }
                else {
                    f[y] = x;
                    sum[x] += sum[y];
                    yr[y] = year;
                }
                continue;
            }
            if(C=='T')
            {
                scanf("%d%d%d",&st,&ed,&t);
                if(anger=( find(st,year)^find(ed,year) ) || (find(st,year-t)==find(ed,year-t)))
                    printf("N
    ");
                else printf("Y
    ");
            }
        }
        return 0;
    }

     样例

    3 3
    R 0 1
    R 0 2
    T 0 2 2

    输出

    Y

  • 相关阅读:
    汉语6级试卷(转)
    看《第一滴血4》
    又爱又恨奥沙利文
    最爱“剁椒鱼头”
    中国移动用户请注意长途电话包有陷阱
    推荐一个免费原版KTV / MTV下载网站
    传说中的人品问题
    信息更改致乒乓球爱好者
    贴几张我家乐乐的照片
    Web Parts: From SharePoint to ASP.NET 2.0
  • 原文地址:https://www.cnblogs.com/CLGYPYJ/p/7486208.html
Copyright © 2020-2023  润新知