發現紹一的人很喜歡作51nod,不得不說這仍是一個很全能的良心OJgit
可是作的這道題就一點都不良心了,簡直是毒瘤,調了一早上數組
首先咱們考慮讓一條路徑的\(a_x\ mod\ a_y\)的值最大,咱們簡單分析一波能夠得出一個結論:spa
當\(a_x\)爲這條路徑上的嚴格次大數,且\(a_y\)爲最大數時,答案最大,且答案爲\(a_x\)。很顯然吧,我來稍微證實一下:code
設最大值爲\(a_u\ mod\ a_v\),則排序
而後咱們有在題目中發現一條十分重要的信息:string
一個點能夠被通過屢次!it
所以一個聯通塊內的點均可以互相到達,所以咱們進行Tarjan縮點,而後考慮拓撲排序更新出最大值最小值io
可是注意一點,一個點只能從一個點轉移過來,剛開始就是沒有考慮到這一點而後WA到死class
具體的操做比較麻煩,仍是看一下CODE吧,解釋一下里面關鍵的幾個數組:im
而後就是細節慢慢的轉移了,尤爲是注意我屢次標註的嚴格
最後莫名在51nod上拿了Rank1,而且甩了Rank2的yekehe一截
CODE
#pragma G++ optimize (2) #pragma comment(linker, "/STACK:10240000,10240000") #include<cstdio> #include<cctype> #include<cstring> using namespace std; const int N=4e5+5,M=2e6+5; struct edge { int to,next; }e[M],ne[M]; int head[N],nhead[N],n,m,q,a[N],max1[N],max2[N],max3[N],max4[N],low[N],dfn[N],col[N],tot,scc,x,y,s,que[N],cnt,stack[N],top,ru[N]; bool vis[N]; inline char tc(void) { static char fl[100000],*A=fl,*B=fl; return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++; } inline void read(int &x) { x=0; char ch; while (!isdigit(ch=tc())); while (x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc())); } inline void write(int x) { if (x>9) write(x/10); putchar(x%10+'0'); } inline void add(int x,int y) { e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt; } inline void nadd(int x,int y) { ne[++cnt].to=y; ne[cnt].next=nhead[x]; nhead[x]=cnt; } inline int min(int a,int b) { return a<b?a:b; } inline int max(int a,int b) { return a>b?a:b; } inline void Tarjan(int now) { dfn[now]=low[now]=++tot; stack[++top]=now; vis[now]=1; for (register int i=head[now];i!=-1;i=e[i].next) if (!dfn[e[i].to]) Tarjan(e[i].to),low[now]=min(low[now],low[e[i].to]); else if (vis[e[i].to]) low[now]=min(low[now],dfn[e[i].to]); if (low[now]==dfn[now]) { col[now]=++scc; vis[now]=0; max1[scc]=a[now]; while (stack[top]!=now) { col[stack[top]]=scc; vis[stack[top]]=0; if (a[stack[top]]>max1[scc]) max2[scc]=max1[scc],max1[scc]=a[stack[top]]; else if (a[stack[top]]>max2[scc]&&a[stack[top]]!=max1[scc]) max2[scc]=a[stack[top]]; --top; } --top; } } inline void top_sort(int s) { int H=0,T=1; que[1]=s; vis[s]=1; while (H<T) { int now=que[++H]; for (register int i=nhead[now];i!=-1;i=ne[i].next) { ++ru[ne[i].to]; if (vis[ne[i].to]) continue; vis[ne[i].to]=1; que[++T]=ne[i].to; } } H=0; T=1; que[1]=s; while (H<T) { int now=que[++H]; for (register int i=nhead[now];i!=-1;i=ne[i].next) { max2[ne[i].to]=max(max2[ne[i].to],max2[now]); if (max1[ne[i].to]!=max3[now]) max2[ne[i].to]=max(max2[ne[i].to],min(max1[ne[i].to],max3[now])); else max2[ne[i].to]=max(max2[ne[i].to],max4[now]); if (max3[now]>max3[ne[i].to]) max4[ne[i].to]=max3[ne[i].to],max3[ne[i].to]=max3[now]; else if (max3[ne[i].to]>max3[now]&&max3[now]>max4[ne[i].to]) max4[ne[i].to]=max3[now]; if (max4[now]>max3[ne[i].to]) max4[ne[i].to]=max3[ne[i].to],max3[ne[i].to]=max4[ne[i].to]; else if (max3[ne[i].to]>max4[now]&&max4[now]>max4[ne[i].to]) max4[ne[i].to]=max4[now]; if (!(--ru[ne[i].to])) que[++T]=ne[i].to; } } } int main() { //freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout); register int i,j; read(n); read(m); read(q); read(s); memset(head,-1,sizeof(head)); memset(e,-1,sizeof(e)); memset(nhead,-1,sizeof(nhead)); memset(ne,-1,sizeof(ne)); for (i=1;i<=n;++i) read(a[i]); for (i=1;i<=m;++i) read(x),read(y),add(x,y); for (i=1;i<=n;++i) if (!dfn[i]) Tarjan(i); for (cnt=0,i=1;i<=n;++i) for (j=head[i];j!=-1;j=e[j].next) if (col[i]!=col[e[j].to]) nadd(col[i],col[e[j].to]); memcpy(max3,max1,sizeof(max3)); memcpy(max4,max2,sizeof(max4)); top_sort(col[s]); while (q--) { read(x); if (!vis[col[x]]) printf("-1 "); else write(max2[col[x]]),putchar(' '); } return 0; }