CodeForces 1200F

Posted tiberius

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces 1200F相关的知识,希望对你有一定的参考价值。

题意略。

思路:

如果是问一下然后搜一下,那必然是不现实的。因此我们要预处理出所有的答案。

我们令mod = lcm(m1,m2,...,mn)。可知,在任意一点,我们挑选两个不同的数c1、c2,其中c2 = k * mod + c1,这两种出发状态一定会走出相同的路径。

由此,我们把每个点拆成mod个状态点,那一共是n * mod个点,由每个状态点只引申出来一条只想别的点的边,我们其实就是要在这个有向图中找环,

找环后统计环上不同点的个数。

开始的时候,我以为环的个数不会超过实际点的个数,后来wa了一次,发现同一个实际点其实是可以在不同的环中的。

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2520005;
const int maxm = 2520005;
const int maxp = 1005;

int connect[maxn],belong[maxn],scc[maxn],cnt;
int stk[maxn],tail;
bool visit[maxn];

int n,mstore[maxp],kstore[maxp],mod = 1;
vector<int> graph[maxp];
set<int> st,sst;

void add_e(int u,int v)
    connect[u] = v;

int gcd(int a,int b)
    return b == 0 ? a : gcd(b,a % b);

int lcm(int a,int b)
    int d = gcd(a,b);
    return a / d * b;

void dfs(int p)
    if(visit[p]) return;
    st.clear();
    sst.clear();
    tail = 0;
    while(!visit[p])
        visit[p] = true;
        stk[tail++] = p;
        st.insert(p);
        p = connect[p];
    
    if(st.count(p))
        int idx = cnt++;
        while(stk[tail - 1] != p)
            int cur = stk[--tail];
            belong[cur] = idx;
            cur = cur / mod + 1;
            sst.insert(cur);
        
        --tail;
        sst.insert(p / mod + 1);
        belong[p] = idx;
        scc[idx] = sst.size();
    
    for(int i = 0;i < tail;++i)
        belong[stk[i]] = belong[p];
     
    


int main()
    scanf("%d",&n);
    for(int i = 1;i <= n;++i) scanf("%d",&kstore[i]);
    for(int i = 1;i <= n;++i)
        scanf("%d",&mstore[i]);
        int m = mstore[i],temp;
        mod = lcm(mod,m);
        for(int j = 0;j < m;++j)
            scanf("%d",&temp);
            graph[i].push_back(temp);
        
    
    for(int i = 1;i <= n;++i)
        int m = mstore[i];
        for(int j = 0;j < mod;++j)
            int to = graph[i][j % m];
            int keep = to;
            to = j + kstore[to];
            to = (to % mod + mod) % mod;
            to = (keep - 1) * mod + to;
            int from = (i - 1) * mod + j;
            add_e(from,to);
        
    
    int tot = n * mod;
    for(int i = 0;i < tot;++i) dfs(i);
    int x,y,q;
    scanf("%d",&q);
    for(int i = 0;i < q;++i)
        scanf("%d%d",&x,&y);
        y = (y + kstore[x]) % mod;
        y = (y + mod) % mod;
        int cur = (x - 1) * mod + y;
        int fa = belong[cur];
        int ans = scc[fa];
        printf("%d\n",ans);
    
    return 0;

 

以上是关于CodeForces 1200F的主要内容,如果未能解决你的问题,请参考以下文章

B. Worms1200 / 二分

题解——Codeforces Round #507 (based on Olympiad of Metropolises) T2(模拟)

B. Young Explorers1200 / 贪心

B. Young Explorers1200 / 贪心

B. AccurateLee难度: 1200 / 贪心

A. Cheap Travel1200 / 暴力