关于重建的模板题

重建
A国拥有N个城市编号为0~N-1,这N个城市由N条双向道路所连接形成了一个环。环上城市的编号沿顺时针方向递增(除第N-1号城市外)。
不幸的是,A国遭遇了一场地震,摧毁了所有N个城市的电力系统。在地震后的K天中,第i天会由城市Ci派出一支重建队伍,他们从第Ci个城市出发,找到顺时针方向上第一个电力系统未被修复的城市并修复它。在该城市电力系统被修复后,所有与它有联系的城市将会向它提供1吨援助物资。城市A与城市B有联系仅当A与B是同一个城市,或者城市A可以沿着道路在只经过电力系统被修复的城市的情况下到达城市B。
请你编写一个程序帮助A国统计在K天的重建过程中的援助物资总量。
输入
一行三个整数N,K,C1
C2到Ck由以下公式计算
Ci=(Ci-1+6655)×1551 % N
输出
输出一个整数,表示重建过程中的援助物资总量
样例输入
6 4 0
样例输出
6

数据规模
对于40%的数据,1≤K<N≤1,000
对于100%的数据,1≤K<N≤3,000,000
时限2s,空间265MB

经过分析,我们可以知道。这道题目的大概意思是:
有N个城市,其中编号分别为0~N-1,各城市与相邻数字相连,形成环。其中编号0城市与编号1相连外,还与编号N-1城市相通。
其次,题目中我们可以发现,每天都有并且只有一个重建队伍在运作,他们在第i天被Ci城市派出,以他们出发的城市开始,顺时针也就是从大到小顺序进行城市重建,他们在该天内只重建1个城市。
同时,题目要求求的援救物资总量,来源于两部分。
一部分是该城市本身为自己提供了1的救援物资,另一部分是附近城市,即指只经过已重建的城市的已重建的城市提供给该城市1的救援物资。
所以,我们计算当天,该城市所得即为1(该城市为自己提供的救援物资)+该城市逆时针开始连续的已完成重建的城市数+该城市逆时针开始连续的已完成重建的城市数。
换句话说,就是该城市包括它自己的连成一片的已完成重建的城市数。

所以,我们可以选择建两个数组,一个表示该城市顺时针到达的第一个未重建的城市next,一个表示该城市逆时针到达的第一个未完成重建的城市before。
那么我们就可以知道,当一个城市完成重建时,那么就会有 (next-before-1)的救援物资发出,为了保证该数据必定大于0,我们可以选择(next-before-1+n)%n 来处理。

代码如下

#include 

using namespace std;

long long  before[3000000],next[3000000];
long long  n,k,now,c,d,ans;
bool bo[3000000];

long long int getfather(int );
long long int getson(int );

inline long long int read()
{
    int x=0;
    char c=getchar();
    while ((c<'0')||(c>'9'))
        c=getchar();
    while ((c>='0')&&(c<='9'))
    {
        x=(x<<3)+(x<<1)+c-'0';
        c=getchar();
    }
    return x;
}

int main()
{
    n=read();
    k=read();
    c=read();
    for (int i=0;i1;
        next[i]=i+1;
    }
    next[n-1]=0;
    before[0]=n-1;
    bo[c]=true;
    ans++;
    now++;
    while (++now<=k)
    {   
        c=(c+6655)*1551%n;
        if (bo[c])
            d=getfather(c);
        else
            d=c;
        bo[d]=true;
        ans+=(getfather(d)-getson(d)-1+n)%n;    
    }
    printf("%lld",ans);
    return 0;
}

long long int getson(int a)
{
    if (bo[before[a]])
        before[a]=getson(before[a]);
    return before[a];
}

long long int getfather(int a)
{
    if (bo[next[a]])
        next[a]=getfather(next[a]);
    return next[a];
}

你可能感兴趣的:(关于重建的模板题)