【省选模拟】—River(贪心)
很显然可以发现对于某一天,一定是选择到达下一步所用时间最小的那一天
也就是在的决策是选择最小的一天
而且对于一个决策一定是固定的
对每一天处理一个下步走多少天的
那在就可以简单解决了
inline ll calc(int p=1,int k=n){
ll res=0;
for(int i=1;i<=k;i++){
int x=(p-1)%m+1;
p=p+nxt[x],res+=nxt[x];
}
return res;
}
结果处理的时候自己手贱把写反了233
在的时候
因为只有,所以路径一定是一个一样的
只需要找到环然后记一下尾巴乱搞一下就可以了
结果意识模糊各种细节出锅233
复杂度,不知道快到哪里去了
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define int long long
const int RLEN=1<<18|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
inline int read(){
char ch=gc();
int res=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-f;ch=gc();}
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return res*f;
}
const int N=2000005;
int n,m;
ll f[N],nxt[N<<1],cir,ans;
inline void init(){
nxt[m<<1]=1e18;
for(int i=(m<<1)-1;~i;--i)nxt[i]=min(nxt[i],nxt[i+1]+1);
}
int dep[N],prelen,len,tot;
void dfs(int u){
int v=(nxt[u]+u)%m;
if(dep[v]){
len=dep[u]-dep[v]+1,prelen=dep[v];
cir=f[dep[u]]-f[dep[v]]+nxt[u];return;
}
dep[v]=++tot;
f[tot]=f[tot-1]+nxt[u];
dfs(v);
}
signed main(){
n=read(),m=read();
for(int i=0;i<m;i++)nxt[i]=nxt[i+m]=read();
init();dep[0]=++tot;
if(n<=tot){
while(n--)ans+=f[ans%m];cout<<ans;return 0;
}
dfs(0);
n-=prelen-1,ans+=f[prelen];
ans+=1ll*(n/len)*cir;
n%=len;
while(n--)ans+=nxt[ans%m];
cout<<ans;
}