Submission #426412

#TimeUsernameProblemLanguageResultExecution timeMemory
426412dualityFrom Hacks to Snitches (BOI21_watchmen)C++11
80 / 100
6022 ms299692 KiB
#include <bits/stdc++.h>
using namespace std;
#define mp make_pair
#define pb push_back
typedef long long int LLI;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef vector<pii> vpii;

vi adjList[250000],adjList2[250000];
pair<int,pii> p[250000];
bool comp(int a,int b) {
    return p[a] < p[b];
}
int pos[250000];
vector<LLI> dist[250000];
priority_queue<pair<LLI,int> > H;
int relax(int u,LLI d) {
    if ((dist[u][d % p[u].first] == -1) || (d < dist[u][d % p[u].first])) {
        dist[u][d % p[u].first] = d;
        H.push(mp(-d,u));
    }
    return 0;
}
int done[250000],done2[250000];
set<pii> done3[250000];
int gcd(int a,int b) {
    int t;
    while (a > 0) t = b % a,b = a,a = t;
    return b;
}
int poss[3000][3000];
int ggcd[3000][3000];
int inv[3000][3000];
vi ll;
int main() {
    int i,j;
    int N,M,K;
    int u,v,l;
    scanf("%d %d",&N,&M);
    for (i = 0; i < M; i++) {
        scanf("%d %d",&u,&v);
        u--,v--;
        adjList[u].pb(v);
        adjList[v].pb(u);
    }
    scanf("%d",&K);
    for (i = 0; i < K; i++) {
        scanf("%d",&l),ll.pb(l);
        for (j = 0; j < l; j++) scanf("%d",&v),p[v-1] = mp(l,mp(j,i));
    }

    int k;
    for (i = 0; i < N; i++) {
        if (p[i].first == 0) p[i].first = 1;
        dist[i].resize(p[i].first);
        fill(dist[i].begin(),dist[i].end(),-1);
    }
    for (i = 0; i < N; i++) {
        sort(adjList[i].begin(),adjList[i].end(),comp);
        while ((pos[i] < adjList[i].size()) && (p[adjList[i][pos[i]]].first == 1)) pos[i]++;
        for (j = 0; j < adjList[i].size(); j++) {
            int v = adjList[i][j];
            if ((p[i].first > 1) && (p[v].first > 1) && (p[i].second.second != p[v].second.second)) adjList2[i].pb(v);
        }
    }
    for (i = 0; i < ll.size(); i++) {
        for (j = 0; j < ll.size(); j++) {
            int g = gcd(ll[i],ll[j]);
            poss[ll[i]/g][(ll[j] % ll[i])/g] = 1;
        }
    }
    for (i = 1; i < 3000; i++) {
        for (j = 0; j <= i; j++) {
            ggcd[i][j] = gcd(i,j);
            if (ggcd[i][j] == 1) {
                if (poss[i][j]) {
                    for (k = 1; k < i; k++) {
                        if (((j*k) % i) == 1) break;
                    }
                    inv[i][j] = k;
                }
            }
        }
    }
    dist[0][0] = 0,H.push(mp(0,0));
    while (!H.empty()) {
        int u = H.top().second;
        LLI d = -H.top().first;
        H.pop();

        if (d > dist[u][d % p[u].first]) continue;
        else if (u == N-1) {
            printf("%lld\n",d);
            return 0;
        }
        if ((p[u].first == 1) || (((d+1) % p[u].first) != p[u].second.first)) relax(u,d+1);
        if (done[u] && (dist[u][(d+p[u].first-1) % p[u].first] == d-1)) {
            for (i = 0; i < adjList2[u].size(); i++) {
                int v = adjList2[u][i];
                if (done3[v].count(mp(d % p[v].first,p[u].first))) continue;
                int a = p[u].first,b = p[v].second.first-d,c = p[v].first;
                b = ((b % c)+c) % c,a %= c;
                int g = gcd(a,c);
                if ((b % g) == 0) {
                    j = (inv[c/g][a/g]*(b/g)) % (c/g);
                    LLI d2 = d+(LLI) j*p[u].first+1;
                    assert((d2 % p[v].first) == ((p[v].second.first+1) % p[v].first));
                    if ((d2 % p[v].first) != p[v].second.first) relax(v,d2);
                }
                done3[v].insert(mp(d % p[v].first,p[u].first));
            }
            continue;
        }
        for (i = done[u] ? pos[u]:0; i < adjList[u].size(); i++) {
            int v = adjList[u][i];
            if (p[v].first == 1) relax(v,d+1);
            else if (p[u].first == 1) {
                if (done2[v]) continue;
                else {
                    for (j = 0; j < p[v].first; j++) {
                        LLI d2 = d+j+1;
                        if ((d2 % p[v].first) != p[v].second.first) relax(v,d2);
                    }
                    done2[v] = 1;
                }
            }
            else if (p[u].second.second == p[v].second.second) {
                if (((d+1) % p[v].first) == p[v].second.first) continue;
                if (((d % p[v].first) == p[v].second.first) && (((d+1) % p[u].first) == p[u].second.first)) continue;
                relax(v,d+1);
            }
            else {
                if (done3[v].count(mp(d % p[v].first,p[u].first))) continue;
                for (j = 0; j < p[v].first; j++) {
                    LLI d2 = d+(LLI) j*p[u].first+1;
                    if ((d2 % p[v].first) != p[v].second.first) relax(v,d2);
                }
                done3[v].insert(mp(d % p[v].first,p[u].first));
            }
        }
        done[u] = 1;
    }
    printf("impossible\n");

    return 0;
}

Compilation message (stderr)

watchmen.cpp: In function 'int main()':
watchmen.cpp:61:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   61 |         while ((pos[i] < adjList[i].size()) && (p[adjList[i][pos[i]]].first == 1)) pos[i]++;
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~
watchmen.cpp:62:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   62 |         for (j = 0; j < adjList[i].size(); j++) {
      |                     ~~^~~~~~~~~~~~~~~~~~~
watchmen.cpp:67:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   67 |     for (i = 0; i < ll.size(); i++) {
      |                 ~~^~~~~~~~~~~
watchmen.cpp:68:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   68 |         for (j = 0; j < ll.size(); j++) {
      |                     ~~^~~~~~~~~~~
watchmen.cpp:99:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   99 |             for (i = 0; i < adjList2[u].size(); i++) {
      |                         ~~^~~~~~~~~~~~~~~~~~~~
watchmen.cpp:115:40: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  115 |         for (i = done[u] ? pos[u]:0; i < adjList[u].size(); i++) {
      |                                      ~~^~~~~~~~~~~~~~~~~~~
watchmen.cpp:40:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   40 |     scanf("%d %d",&N,&M);
      |     ~~~~~^~~~~~~~~~~~~~~
watchmen.cpp:42:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   42 |         scanf("%d %d",&u,&v);
      |         ~~~~~^~~~~~~~~~~~~~~
watchmen.cpp:47:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   47 |     scanf("%d",&K);
      |     ~~~~~^~~~~~~~~
watchmen.cpp:49:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   49 |         scanf("%d",&l),ll.pb(l);
      |         ~~~~~^~~~~~~~~
watchmen.cpp:50:38: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   50 |         for (j = 0; j < l; j++) scanf("%d",&v),p[v-1] = mp(l,mp(j,i));
      |                                 ~~~~~^~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...