板子
算法枚举
- DP,贪心,二分
- 核心:找规律,观察性质
- 套 DS : 扫描线,线段树,BIT,平衡树?堆,单调栈/队列
技巧枚举
- 正难则反,根号分治,前后考虑,拆贡献,转化
字符串
KMP
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define fi first
#define se second
#define in inline
#define pb push_back
const int N = 1e6+10;
ll read(){
ll x = 0,f = 1;char c = getchar();
for(;c < '0' || c > '9';c = getchar())if(c == '-')f = -1;
for(;c >= '0' && c <= '9';c = getchar())x = (x<<1) + (x<<3) + c-'0';
return x * f;
}
char a[N],b[N];
int nx[N],p[N],l1,l2;
vector<int>ans;
int main(){
scanf("%s%s",a + 1,b + 1);
l1 = strlen(a + 1),l2 = strlen(b + 1);
for(int i = 2,j = 0;i <= l2;i++){
while(j > 0 && b[i] != b[j+1])j = nx[j];
if(b[i] == b[j+1])j++;
nx[i] = j;
}
for(int i = 1,j = 0;i <= l1;i++){
while(j > 0 && a[i] != b[j+1])j = nx[j];
if(a[i] == b[j+1])j++;
if(j == l2)ans.pb(i - l2 + 1);//匹配节点
}
for(int x : ans)printf("%d\n",x);
for(int i = 1;i <= l2;i++)printf("%d ",nx[i]);//border
return 0;
}
后缀数组
int n,m,p;
char c[N];
int sa[N],rk[N],ork[N<<1],id[N],cnt[N];
bool cmp(int a,int b,int w){return ork[a] == ork[b] && ork[a + w] == ork[b + w];}
//若与相等的不加,否则加
int main(){
scanf("%s",c+1);
n = strlen(c+1),m = 128;
for(int i = 1;i <= n;i++)cnt[rk[i] = c[i]]++;
for(int i = 1;i <= m;i++)cnt[i] += cnt[i-1];
for(int i = n;i >= 1;i--)sa[cnt[rk[i]]--] = i;
for(int w = 1;;w <<= 1,m = p,p = 0){
for(int i = n - w + 1;i <= n;i++)id[++p] = i;
for(int i = 1;i <= n;i++)
if(sa[i] > w)id[++p] = sa[i] - w;
memset(cnt,0,sizeof cnt);
for(int i = 1;i <= n;i++)cnt[rk[i]]++;
for(int i = 1;i <= m;i++)cnt[i] += cnt[i-1];
for(int i = n;i >= 1;i--)sa[cnt[rk[id[i]]]--] = id[i];
p = 0;
memcpy(ork,rk,sizeof rk);
for(int i = 1;i <= n;i++)rk[sa[i]] = cmp(sa[i-1],sa[i],w) ? p : ++p;
if(p == n)break;
}
for(int i = 1;i <= n;i++){
if(p)p--;
while(c[i + p] == c[sa[rk[i] - 1] + p])p++;
ht[rk[i]] = p;
}
for(int i = 1;i <= n;i++)printf("%d ",sa[i]);
printf("\n");
return 0;
}
数学
\(\mathcal{O}(1)\) 龟速乘
ll mul(ll x,ll y,ll p){return (x*y-(ll)(x/(long double)p*y+1e-3)*p+p) % p;}
三分
int n;
double a[N],b[N],c[N];
double f(double x){
double ans = -1e8;
for(int i = 1;i <= n;i++)ans = max(ans,a[i] * x * x + b[i] * x + c[i]);
return ans;
}
void solve(){
n = read();
for(int i = 1;i <= n;i++)a[i] = read(),b[i] = read(),c[i] = read();
double l = 0,r = 1000;
while(l + eps < r){
double mid1 = (l + r) / 2.0;
double mid2 = (mid1 + r) / 2.0;
if(f(mid1) + eps < f(mid2))r = mid2;
else l = mid1;
}
printf("%.4lf\n",f(l));
}
int main(){
int t = read();
while(t--)solve();
return 0;
}
扩展欧拉定理
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<ll,ll>
#define fi first
#define se second
#define pb push_back
const int N = 2e5+10;
ll read(){
ll x = 0,f = 1;char c = getchar();
for(;c < '0' || c > '9';c = getchar())if(c == '-')f = -1;
for(;c >= '0' && c <= '9';c = getchar())x = (x<<1) + (x<<3) + c-'0';
return x * f;
}
ll n,p,m;
ll phi(ll x){
if(x == 1)return 1;
ll ans = x;
for(ll i = 2;i <= sqrt(x);i++){
if(x % i == 0){
ans = ans / i * (i - 1);
while(x % i == 0)x /= i;
}
}
if(x > 1)ans = ans / x * (x - 1);
return ans;
}
ll ksm(ll x,ll y){
ll ans = 1;
while(y){
if(y & 1)ans = ans * x % p;
x = x * x % p,y >>= 1;
}return ans;
}
int main(){
n = read(),p = read();
ll p2 = phi(p);
char c = getchar();
bool f = 0;
for(;c >= '0' && c <= '9';c = getchar()){
m = (m<<1) + (m<<3) + c-'0';
if(m >= p2)f = 1,m %= p2;
}
printf("%lld\n",ksm(n,m + f * p2));
return 0;
}
拉格朗日插值
\(f(x) = \sum\limits_{i=1}^n y_i \prod\limits_{i \not = j} {\dfrac {x - x_j} {x_i - x_j}}\)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define fi first
#define in inline
#define se second
#define mp make_pair
#define pb push_back
const int N = 2e3+10;
const ll mod = 998244353;
ll read(){
ll x = 0,f = 1;char c = getchar();
for(;c < '0' || c > '9';c = getchar())if(c == '-')f = -1;
for(;c >= '0' && c <= '9';c = getchar())x = (x<<1) + (x<<3) + c-'0';
return x * f;
}
int n;
ll x[N],y[N],k;
ll ksm(ll x,ll y){
ll ans = 1;
while(y){
if(y & 1)ans = ans * x % mod;
x = x * x % mod,y >>= 1;
}return ans;
}
int main(){
n = read(),k = read();
for(int i = 1;i <= n;i++)x[i] = read(),y[i] = read();
ll ans = 0;
for(int i = 1;i <= n;i++){
ll s = y[i] % mod;
for(int j = 1;j <= n;j++){
if(i == j)continue;
s = s * (k - x[j] + mod) % mod;
s = s * ksm((x[i] - x[j] + mod) % mod,mod - 2) % mod;
}
(ans += s) %= mod;
}
printf("%lld\n",ans);
return 0;
}
线性筛
void pre(int n){
for(int i = 2;i <= n;i++){
if(!v[i])p[++cnt] = i;
for(int j = 1;j <= cnt && i <= n / p[j];j++){
v[i * p[j]] = 1;
if(i % p[j] == 0)break;
}
}
}
中国剩余定理
int n;
ll a[N],b[N];
void exgcd(ll a,ll b,ll &x,ll &y){
if(b == 0){return x = 1,y = 0,void();}
exgcd(b,a%b,y,x);
y -= a / b * x;
}
ll mul(ll x,ll y,ll p){return (x*y-(ll)(x/(long double)p*y+1e-3)*p+p) % p;}
ll lcm(ll x,ll y){return x / __gcd(x,y) * y;}
ll EXCRT(){
ll x = a[1],M = b[1],k = 0,y = 0;
F(i,2,n){
ll gc = __gcd(M,b[i]);
if((a[i]-x) % gc != 0)return -1;//无解
exgcd(M,b[i],k,y);
ll mod = b[i] / gc;
k = (mul(k,(a[i] - x) / gc,mod) + mod) % mod;
x = x + k * M;
M = lcm(M,b[i]);
}//EXCRT
return x;
}
int main(){
n = read();
F(i,1,n)b[i] = read(),a[i] = read();
printf("%lld\n",EXCRT());
return cerr<<endl<<"Time:"<<clock()<<"ms"<<endl,0;
}
高斯消元
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define db double
#define in inline
#define re register
#define pii pair<int,int>
#define fi first
#define se second
#define pb(x) push_back(x)
#define D(i,a,b) for(re long double i = a;i >= b;i--)
#define F(i,a,b) for(re long long i = a;i <= b;i++)
const int N = 110;
const ll inf = 1e17;
ll read(){
ll x = 0,f = 1;char c = getchar();
for(;c < '0' || c > '9';c = getchar())if(c == '-')f = -1;
for(;c >= '0' && c <= '9';c = getchar())x = (x<<1) + (x<<3) + c-'0';
return x * f;
}
int n;
db a[N][N],b[N];
int main(){
// freopen("zfx.in","r",stdin);
// freopen("zfx.out","w",stdout);
n = read();
for(int i = 1;i <= n;i++){
for(int j = 1;j <= n;j++)a[i][j] = read();
b[i] = read();
}
for(int i = 1;i <= n;i++){
int k = i;
for(int j = i+1;j <= n;j++)
if(fabs(a[j][i]) > fabs(a[k][i]))k = j;
for(int j = 1;j <= n;j++)swap(a[i][j],a[k][j]);swap(b[i],b[k]);
if(fabs(a[i][i]) < 1e-8)return printf("No Solution\n"),0;
db c = a[i][i];
for(int j = 1;j <= n;j++)a[i][j] /= c;b[i] /= c;
for(int j = 1;j <= n;j++){
if(i == j)continue;
db c = a[j][i];
for(int k = i;k <= n;k++)a[j][k] -= c * a[i][k];
b[j] -= c * b[i];
}
}
for(int i = 1;i <= n;i++){
printf("%.2lf\n",b[i]);
}
return cerr << "Time : " << clock() << " ms" << endl, 0;
}
图论
单源最短路径
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<ll,ll>
#define fi first
#define se second
#define pb push_back
const int N = 2e5+10;
ll read(){
ll x = 0,f = 1;char c = getchar();
for(;c < '0' || c > '9';c = getchar())if(c == '-')f = -1;
for(;c >= '0' && c <= '9';c = getchar())x = (x<<1) + (x<<3) + c-'0';
return x * f;
}
int n,m,s;
vector<pii>e[N];
priority_queue<pii,vector<pii>,greater<pii> >q;
ll d[N];
bool v[N];
void dij(int s){
memset(v,0,sizeof v);
for(int i = 1;i <= n;i++)d[i] = 1e17;
d[s] = 0,q.push({0,s});
while(!q.empty()){
int x = q.top().se;q.pop();
if(v[x])continue;
v[x] = 1;
for(auto it : e[x]){
int y = it.fi;ll z = it.se;
if(d[y] > d[x] + z){
d[y] = d[x] + z;
q.push({d[y],y});
}
}
}
}
int main(){
n = read(),m = read(),s = read();
for(int i = 1;i <= m;i++){
int x = read(),y = read();ll z = read();
e[x].pb({y,z});
}
dij(s);
for(int i = 1;i <= n;i++)printf("%lld ",d[i]);
printf("\n");
return 0;
}
欧拉路径
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
const int N = 2e5+10;
ll read(){
ll x = 0,f = 1;char c = getchar();
for(;c < '0' || c > '9';c = getchar())if(c == '-')f = -1;
for(;c >= '0' && c <= '9';c = getchar())x = (x<<1) + (x<<3) + c-'0';
return x * f;
}
int n,m,rt;
int st[N],in[N],hd[N],top;
vector<int>e[N];
void dfs(int x){
for(int &i = hd[x];i < (int)e[x].size();)dfs(e[x][i++]);
st[++top] = x;//倒序
}
int main(){
n = read(),m = read();
for(int i = 1;i <= m;i++){
int x = read(),y = read();
e[x].pb(y),in[y]++;
}
for(int i = 1;i <= n;i++){
sort(e[i].begin(),e[i].end());
if(abs((int)e[i].size() - in[i]) > 1)return printf("No\n"),0;
if(e[i].size() > in[i]){
if(rt)return printf("No\n"),0;
else rt = i;
}//
}
dfs(rt ? rt : 1);
if(top != m + 1)return printf("No\n"),0;
for(int i = top;i >= 1;i--)printf("%d ",st[i]);
return 0;
}
tarjan 缩点
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define fi first
#define se second
#define in inline
#define pb push_back
const int N = 1e4+10;
ll read(){
ll x = 0,f = 1;char c = getchar();
for(;c < '0' || c > '9';c = getchar())if(c == '-')f = -1;
for(;c >= '0' && c <= '9';c = getchar())x = (x<<1) + (x<<3) + c-'0';
return x * f;
}
int n,m;
int a[N];
vector<int>e[N],E[N];
int dfn[N],low[N],st[N],c[N],s[N];
int top,cnt,num;
bool v[N];
void tarjan(int x){
dfn[x] = low[x] = ++cnt;
st[++top] = x,v[x] = 1;
for(int y : e[x]){
if(!dfn[y])tarjan(y),low[x] = min(low[x],low[y]);
else if(v[y])low[x] = min(low[x],dfn[y]);
}
if(dfn[x] == low[x]){
int y = 0;num++;
do{
y = st[top--];
v[y] = 0,c[y] = num,s[num] += a[y];
}while(x != y);
}
}
int f[N],ru[N],ans;
void topsort(){//
queue<int>q;
for(int i = 1;i <= num;i++)
if(!ru[i])q.push(i),f[i] = s[i];
while(!q.empty()){
int x = q.front();q.pop();
ans = max(ans,f[x]);
for(int y : E[x]){
f[y] = max(f[y],f[x] + s[y]);
if(!(--ru[y]))q.push(y);
}
}
printf("%d\n",ans);
}
map<pii,bool>mp;
int main(){
n = read(),m = read();
for(int i = 1;i <= n;i++)a[i] = read();
for(int i = 1;i <= m;i++){
int x = read(),y = read();
e[x].pb(y);
}
for(int i = 1;i <= n;i++)
if(!dfn[i])tarjan(i);//tarjan
for(int x = 1;x <= n;x++){
for(int y : e[x]){
if(c[x] == c[y])continue;
if(!mp[{c[x],c[y]}])E[c[x]].pb(c[y]),ru[c[y]]++,mp[{c[x],c[y]}] = 1;
}
}//重建图
topsort();
return 0;
}
点双
void tarjan(int x){
low[x] = dfn[x] = ++cnt;
int flag = 0;
if(x == root && !hd[x])ans[++num].push_back(x);
st[++top] = x;
for(int i = hd[x];i;i = e[i].nx){
int y = e[i].ver;
if(!dfn[y]){
tarjan(y);low[x] = min(low[x],low[y]);
if(dfn[x] <= low[y]){
num++;
int p = 0;
do{
p = st[top];top--;
ans[num].push_back(p);
}while(p != y);
ans[num].push_back(x);
}
}
else low[x] = min(low[x],dfn[y]);
}
}
数据结构
单调队列
//19:02
int n,m;
int a[N],q[N],l = 1,r;
int main(){
n = read(),m = read();
for(int i = 1;i <= n;i++)a[i] = read();
for(int i = 1;i <= n;i++){
while(l <= r && q[l] < i - m + 1)l++;
while(l <= r && a[i] <= a[q[r]])r--;
q[++r] = i;
if(i >= m)printf("%d ",a[q[l]]);
}
printf("\n");
l = 1,r = 0;
for(int i = 1;i <= n;i++){
while(l <= r && q[l] < i - m + 1)l++;
while(l <= r && a[i] >= a[q[r]])r--;
q[++r] = i;
if(i >= m)printf("%d ",a[q[l]]);
}
printf("\n");
return 0;
}
ST 表
//19:14
int n,q;
int a[N],st[N][22];
int main(){
n = read(),q = read();
for(int i = 1;i <= n;i++)a[i] = read(),st[i][0] = a[i];
for(int j = 1;j <= 20;j++)
for(int i = 1;i + (1 << j) - 1 <= n;i++)st[i][j] = max(st[i][j-1],st[i + (1 << j - 1)][j-1]);
for(int i = 1;i <= q;i++){
int l = read(),r = read();
int p = log2(r-l+1);
printf("%d\n",max(st[l][p],st[r-(1<<p)+1][p]));
}
return 0;
}
线段树
//19:20
int n,q,mod;
int a[N];
struct segment{
ll s[N<<2],la[N<<2],tag[N<<2];
void pushup(int p){s[p] = (s[p<<1] + s[p<<1|1]) % mod;}
void update(int p,ll k1,ll k2,int l,int r){
s[p] = s[p] * k1 % mod + (ll)(r - l + 1) * k2 % mod;
la[p] = la[p] * k1 % mod;
tag[p] = (tag[p] * k1 % mod + k2) % mod;
}
void pushdown(int p,int l,int r){
int mid = l + r >> 1;
update(p<<1,la[p],tag[p],l,mid),update(p<<1|1,la[p],tag[p],mid+1,r);
la[p] = 1,tag[p] = 0;
}
void build(int p,int l,int r){
la[p] = 1;
if(l == r)return s[p] = a[l],void();
int mid = l + r >> 1;
build(p<<1,l,mid),build(p<<1|1,mid+1,r);
pushup(p);
}
void modify1(int p,int l,int r,int L,int R,ll k){
if(L <= l && r <= R)return update(p,k,0,l,r),void();
int mid = l + r >> 1;
pushdown(p,l,r) ;
if(L <= mid)modify1(p<<1,l,mid,L,R,k);
if(R > mid)modify1(p<<1|1,mid+1,r,L,R,k);
pushup(p);
}
void modify2(int p,int l,int r,int L,int R,ll k){
if(L <= l && r <= R)return update(p,1,k,l,r),void();
int mid = l + r >> 1;
pushdown(p,l,r);
if(L <= mid)modify2(p<<1,l,mid,L,R,k);
if(R > mid)modify2(p<<1|1,mid+1,r,L,R,k);
pushup(p);
}
ll ask(int p,int l,int r,int L,int R){
if(L > r || R < l)return 0;
if(L <= l && r <= R)return s[p];
int mid = l + r >> 1;
pushdown(p,l,r);
return (ask(p<<1,l,mid,L,R) + ask(p<<1|1,mid+1,r,L,R)) % mod;
}
}t;
int main(){
n = read(),q = read(),mod = read();
for(int i = 1;i <= n;i++)a[i] = read();
t.build(1,1,n);
for(int i = 1;i <= q;i++){
int op = read(),l = read(),r = read();
if(op == 1){
ll k = read();
t.modify1(1,1,n,l,r,k);
}
else if(op == 2){
ll k = read();
t.modify2(1,1,n,l,r,k);
}
else printf("%lld\n",t.ask(1,1,n,l,r));
}
return 0;
}
字典树
int n,q;
int s[N][110],sum[N],cnt = 1;
void add(char *ch){
int len = strlen(ch),p = 1;
for(int i = 0;i < len;i++){
int c = ch[i] - 'a';
if(ch[i] >= '0' && ch[i] <= '9')c = 26 + ch[i] - '0';
if(ch[i] >= 'A' && ch[i] <= 'Z')c = 36 + ch[i] - 'A';
if(!s[p][c])s[p][c] = ++cnt;
p = s[p][c];
sum[p]++;
}
}
ll ask(char *ch){
int len = strlen(ch),p = 1;
for(int i = 0;i < len;i++){
int c = ch[i] - 'a';
if(ch[i] >= '0' && ch[i] <= '9')c = 26 + ch[i] - '0';
if(ch[i] >= 'A' && ch[i] <= 'Z')c = 36 + ch[i] - 'A';
if(!s[p][c])return 0;
p = s[p][c];
}
return sum[p];
}
char c[N];
void solve(){
n = read(),q = read();
for(int i = 1;i <= n;i++){
scanf("%s",c);
add(c);
}
for(int i = 1;i <= q;i++){
scanf("%s",c);
printf("%lld\n",ask(c));
}
for(int i = 1;i <= cnt;i++)
for(int j = 0;j < 100;j++)s[i][j] = 0,sum[i] = 0;
cnt = 1;
}
李超树
struct line{
db k,b = -inf;
int id;
line(db k,db b,int id):k(k),b(b),id(id){}
line(){}
db val(int x){return k * x + b;}
};
bool cmp(line a,line b,int x){return (fabs(a.val(x) - b.val(x)) < eps) ? a.id < b.id : a.val(x) > b.val(x);}
struct LiChao_tree{
line mx[N<<5];
line ask(line a,line b,int x){return cmp(a,b,x) ? a : b;}
void modify(int p,int l,int r,line x){
if(l > r)return;
int mid = l + r >> 1;
if(cmp(x,mx[p],mid))swap(mx[p],x);
if(cmp(x,mx[p],l))modify(p<<1,l,mid,x);
if(cmp(x,mx[p],r))modify(p<<1|1,mid+1,r,x);
}
void modify(int p,int l,int r,int L,int R,line x){
if(L <= l && r <= R)return modify(p,l,r,x),void();
int mid = l + r >> 1;
if(L <= mid)modify(p<<1,l,mid,L,R,x);
if(R > mid)modify(p<<1|1,mid+1,r,L,R,x);
}
line query(int p,int l,int r,int x){
if(l == r)return mx[p];
int mid = l + r >> 1;
if(x <= mid)return ask(query(p<<1,l,mid,x),mx[p],x);
else return ask(query(p<<1|1,mid+1,r,x),mx[p],x);
}
}t;
int main(){
scanf("%d",&n);
for(int i = 1;i <= n;i++){
int op,a,b,c,d;
scanf("%d%d",&op,&a);a = (a+las-1)%m1+1;
if(op == 0)printf("%d\n",las = t.query(1,1,m1,a).id);
else{
scanf("%d%d%d",&b,&c,&d);
b = (b+las-1)%m2+1,c = (c+las-1)%m1+1,d = (d+las-1)%m2+1;
if(a > c)swap(a,c),swap(b,d);
double k = 0,B = 0;
if(a == c)B = max(b,d);
else k = (double)(d - b) / (c - a),B = (double)b - a * k;
t.modify(1,1,m1,a,c,{k,B,++m});
}
}
return 0;
}
平衡树
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5+10;
const ll inf = 1e17;
int n,m,R;
struct FHQ{
int val[N],rd[N],size[N],ls[N],rs[N],la[N],idx = 0;
void pushup(int p){size[p] = size[ls[p]] + size[rs[p]] + 1;}
void pushdown(int p){
if(!la[p])return;
la[ls[p]] ^= 1,la[rs[p]] ^= 1;
swap(ls[p],rs[p]),la[p] = 0;
}
int node(int v){
int x = ++idx;
val[x] = v,size[x] = 1,rd[x] = rand(),ls[x] = rs[x] = la[x] = 0;
return x;
}
void split(int p,int v,int &x,int &y){
if(!p)return x = y = 0,void();
pushdown(p);
if(v <= size[ls[p]])y = p,split(ls[p],v,x,ls[p]);
else x = p,split(rs[p],v-size[ls[p]]-1,rs[p],y);
pushup(p);
}
int merge(int x,int y){
if(!x || !y)return x|y;
pushdown(x),pushdown(y);
if(rd[x] < rd[y])return ls[y] = merge(x,ls[y]),pushup(y),y;
else return rs[x] = merge(rs[x],y),pushup(x),x;
}
void insert(int v){
int x = 0,y = 0;
split(R,v-1,x,y),R = merge(merge(x,node(v)),y);
}
void reserve(int l,int r){
int x = 0,y = 0,z = 0;
split(R,r,x,z),split(x,l-1,x,y);
la[y] ^= 1;
R = merge(merge(x,y),z);
}
void prin(int x){
if(!x)return;
pushdown(x);
prin(ls[x]);
printf("%d ",val[x]);
prin(rs[x]);
}
}t;
int main(){
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i++)t.insert(i);
for(int i = 1;i <= m;i++){
int x,y;scanf("%d%d",&x,&y);
t.reserve(x,y);
}
t.prin(R);
printf("\n");
return 0;
}
数位 DP
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5+10;
const ll inf = 1e17;
ll l,r;
ll f[15],ksm[15],c[15],now[15];
ll dfs(int p,int x,bool f0,bool lim){
if(!p)return 0;
if(!f0 && !lim && f[p] != -1)return f[p];
ll cnt = 0;
int lst = lim ? c[p] : 9;
for(int i = 0;i <= lst;i++){
if(f0 && i == 0)cnt += dfs(p-1,x,1,lim && (i==lst));
else if(i == x && lim && i == lst)cnt += now[p-1] + 1 + dfs(p-1,x,0,lim && (i==lst));
else if(i == x)cnt += ksm[p-1] + dfs(p-1,x,0,lim && (i==lst));
else cnt += dfs(p-1,x,0,lim && (i==lst));
}
if(!lim && !f0)f[p] = cnt;
return cnt;
}
ll sum(ll d,ll x){
int l = 0;
memset(f,-1,sizeof f);
memset(now,0,sizeof now);
while(d){
c[++l] = d % 10;
d /= 10;
now[l] = now[l-1] + ksm[l-1] * c[l];
}
return dfs(l,x,1,1);
}
int main(){
ksm[0] = 1;
for(int i = 1;i <= 12;i++)ksm[i] = ksm[i - 1] * 10ll;
scanf("%lld%lld",&l,&r);
if(l > r)swap(l,r);
for(int i = 0;i <= 9;i++)printf("%lld ",sum(r,i) - sum(l-1,i));
printf("\n");
return 0;
}