Single Round Match 524 Round 1 - Division I, Level Two LongestSequence

来源:互联网 发布:服装批发开单软件 编辑:程序博客网 时间:2024/06/06 15:44

首先观察发现,如果有长度限制的话,最长不会超过最大值得两倍。首先有长度限制必然出现在有正有负的情况下,手推几个简单的例子就能看出来。

那么我们用sum[i]表示前i个的前缀和。那么C[i]<0就表示sum[k+C[i]]-sum[k]<0即sum[k+C[i]]<sum[k]。同理C[i]>0我们也可以得到不等关系。那么就可以建图了,对于不等式sum[a]<sum[b],就建一点从a到b的又向边。如果这个图中出现了环(大于一个点的强联通分量),就意味着无解。

我们二分一个答案n,就意味着有从sum[0],sum[1],sum[2],...sum[n]这n+1个点,建好图后跑一次tarjan算法即可。

#include <bits/stdc++.h>#define maxn 2009#define maxm 4000009using namespace std;struct Edge{int v,next;}edge[maxm];int head[maxn],tot,n,m;int dfn[maxn],low[maxn],stk[maxn],in[maxn],cnt[maxn],top,dfs_time,bcnt;int a[maxn],num;void tarjan(int u){low[u]=dfn[u]=++dfs_time;in[u]=1;stk[++top]=u;for(int e=head[u];e!=-1;e=edge[e].next){int v=edge[e].v;if(!dfn[v]){tarjan(v);low[u]=min(low[u],low[v]);}else if(in[v]){low[u]=min(low[u],dfn[v]);}}if(low[u]==dfn[u]){int x;bcnt++;cnt[bcnt]=0;do{x=stk[top--];in[x]=0;cnt[bcnt]++;}while(x!=u);}}void addedge(int u,int v){edge[tot].v=v;edge[tot].next=head[u];head[u]=tot++;}bool check(int mid){n=mid;memset(head,-1,sizeof(head));tot=0;for(int j=0;j<num;j++){int len=abs(a[j]);for(int i=0;i+len<n;i++){if(a[j]<0)addedge(i,i+len);elseaddedge(i+len,i);}}memset(dfn,0,sizeof(dfn));dfs_time=bcnt=0;for(int i=0;i<n;i++){if(!dfn[i])tarjan(i);}for(int i=1;i<=bcnt;i++){if(cnt[i]>1)return 0;}return 1;}class LongestSequence{public:int maxLength(vector <int> C){num=C.size();for(int i=0;i<num;i++)a[i]=C[i];if(check(2002))return -1;int L=0,R=2002;while(L<R){int M=(L+R+1)>>1;if(check(M))L=M;elseR=M-1;}return L-1;}};


0 0
原创粉丝点击