E Graduated Lexicographical Ordering

数位dp

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<cctype>
#include<ctime>
#include<vector>
#include<set>
#include<string>
#include<queue>
#include<complex>
#include<stack>
using namespace std;
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma
#define
#define
#define
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
void upd(ll &a,ll b){a+=b;}
#define
char a[MAXN];
int n;
ll f[MAXN][10][2][10*18+10][2];
ll cnt[9*18+1];
bool vis[MAXN][10][2][10*18+10][2]={};
ll g[MAXN][10][2][10*18+10][2]={};
ll dfs(int i,int j,int k,int x,int y) {
if (i==n) return g[i][j][k][x][y]=(x==0);
if (vis[i][j][k][x][y]) {
return g[i][j][k][x][y];
}
vis[i][j][k][x][y]=1;
g[i][j][k][x][y]=0;
Rep(t,10) if (t<=x){
int nk=k|(t>0);
int nx=x-t,ny=(y&&t==a[i+1]);
if (y&&t>a[i+1]) continue;
upd(g[i][j][k][x][y],dfs(i+1,t,nk,nx,ny));
}
return g[i][j][k][x][y];
}
char s[200];
void get_kth(ll W ,bool fl,ll w,ll sz ) {
if (!fl) {
w=1,sz=0;
while(sz+cnt[w]<W)
sz+=cnt[w++];
MEM(g) MEM(vis)
dfs(0,0,0,w,1);
}
ll len=0,wsum=w,y=1,k=0;
bool is_gre=0;
while(1) {
++len;
Rep(t,10) if (t<=W){
if (t==0 &&!k) continue;
s[len]=t+'0';
ll ny=(y&&t==a[len]);
ll nk=k|(t>0);
ll pans=0;
Fork(i,len,n) {
if (i==len && (t>a[len] && y ||is_gre)) continue;
pans+=g[i][t][nk][wsum-t][(i==len)&&ny];
}
if (sz+pans>=W) {
if (t>a[len] && y) {
is_gre=1;
}
y=ny,k=nk;

break;
}else sz+=pans;
}

s[len+1]=0;
wsum-=s[len]-'0';
if (sz+1==W&&!wsum) break;
if (!wsum) ++sz;
}
}
char b[100];
bool cmp() {
int i=1;
// cout<<s+1<<' '<<b+1<<endl;
while(s[i]+b[i]) {
if (s[i]^b[i]) return s[i]<b[i];
++i;
}
return 1;
}
void calc(ll k) {
int len2=0;
while(k) {
b[++len2]='0'+k%10;
k/=10LL;
}
b[len2+1]=0;
reverse(b+1,b+1+len2);
ll w=0;
For(i,len2) b[i]-='0',w+=b[i];

ll sz=0;
For(i,w-1) sz+=cnt[i];
MEM(g) MEM(vis)
dfs(0,0,0,w,1);

For(i,len2) b[i]+='0';
ll L=sz+1,R=sz+cnt[w],ans=L;

while(L<=R) {
ll m=(L+R)/2;
// cout<<m<<endl;
get_kth(m,1,w,sz);
if (cmp()) L=m+1,ans=m;
else R=m-1;
}
cout<<ans<<endl;
}
int main()
{
freopen("grlex.in","r",stdin);
freopen("grlex.out","w",stdout);
scanf("%s",a+1);
ll ans=0;
n=strlen(a+1);
For(i,n) a[i]-='0';
MEM(f)
f[0][0][0][0][1]=1;
Rep(i,n) {
Rep(j,10) Rep(k,2) Rep(x,i*10+1) Rep(y,2) {
if (f[i][j][k][x][y]) {
Rep(t,10) {
int nk=k|(t>0);
int nx=x+t,ny=(y&&t==a[i+1]);
if (y&&t>a[i+1]) continue;
upd(f[i+1][t][nk][nx][ny],f[i][j][k][x][y]);
}
}
}
}
Rep(j,10) Rep(k,2) Rep(x,n*10+1) Rep(y,2) {
cnt[x]+=f[n][j][k][x][y];
}
ll k;
cin>>k;

calc(k);
// For(k,200) {
// get_kth(k,0,0,0);
// cout<<s+1<<endl;
// }
get_kth(k,0,0,0);
cout<<s+1<<endl;
// Fork(k,2064,2174) {
// get_kth(k,0,0,0);
// cout<<s+1<<endl;
// }
return 0;
}

H Don’t Go Left

给一个自动机,然后模拟上面的操作,问磁带是否会回退?

根据题意写记忆化搜索

#include<bits/stdc++.h> 
using namespace std;
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma
#define
#define
#define
#define
#define
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
// #define ONLINE_JUDGE
string Filename="left";
int f[120][120]={},n,m;
int a[120][120]={},c[120][120]={};
int vis[120][120][120]={};
bool dfs(int x,int p,int ed) { //p<=m+1 ' '
if (x==n) return 1;
else if (vis[x][p][ed]>=0) return vis[x][p][ed];
else if (vis[x][p][ed]==-2) return 1;
else {
// cout<<x<<" "<<p<<' '<<ed<<endl;
vis[x][p][ed]=-2;
if (p==m+1) {
For(j,m-1) {
int v=(a[x][j]==1)?(m+1):c[x][j];
if (a[x][j]==-1) return vis[x][p][ed]=0;
if (!dfs(f[x][j],v,ed)) return vis[x][p][ed]=0;
}
int v=(a[x][m]==1)?(m):c[x][m];
if (a[x][m]==-1) return vis[x][p][ed]=0;
if (!dfs(f[x][m],v,1)) return vis[x][p][ed]=0;
return vis[x][p][ed]=1;

} else {
if (a[x][p]==-1) return vis[x][p][ed]=0;
return vis[x][p][ed]=dfs(f[x][p],(a[x][p]==1)?((ed)?m:(m+1) ):c[x][p],ed);
}
}
}

int main()
{
fr("left.in");
fw("left.out");
MEMx(vis,-1)
n=read(),m=read();
For(i,n-1) {
For(j,m) {
f[i][j]=read();
c[i][j]=read();
a[i][j]=read();
}
}
puts(dfs(1,m+1,0)? "YES":"NO");
return 0;
}