2013-team5/andrew/30/D
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
typedef pair <int, int> PII;
const int INF=1e8, MN=1e6+7;
LL l,r,f[30],v[30];
LL C[40][40];
void comb(){
C[0][0]=1;
for (int i=1; i<=20; i++){
C[i][0]=1;
for (int j=1; j<i; j++)
C[i][j]=C[i-1][j-1]+C[i-1][j];
C[i][i]=1;
}
}
LL A(int n,int m){
LL ans=1;
for (LL i=n-m+1; i<=n; i++) ans*=i;
return ans;
}
LL calc(int k0){
int i,j,k=k0,n=0,m=0;
for (i=0; i<10; i++)
if (v[i]>0){
n++;
m+=v[i]==2;
}
LL ans=0;
for (i=0; i<=m && k>=0; i++,k-=2){
LL tmp=A(n-i,k)*C[m][i];
for (j=k+2; j<=k0; j+=2) tmp*=C[j][2];
ans+=tmp;
}
return ans;
}
LL gao(LL s){
if (s==0) return 0;
LL w=s;
int t[30]={};
while (s){ t[++t[0]]=s%10; s/=10; }
int i,j;
LL ans=0;
v[0]--;
for (i=t[0]-1; i>=2; i--){
ans+=calc(i-1)*9ll;
}
v[0]++;
if (t[0]>1) ans+=9;
for (i=t[0]; i>=1; i--){
for (j=(i==t[0])?1:0; j<t[i]; j++) if (v[j]>0){
v[j]--;
ans+=calc(i-1);
v[j]++;
}
if (--v[t[i]]<0) break;
}
/* int flag=1;
for (i=1; i<=t[0]; i++)
if (v[i]<0) flag=0;
*/
int flag=1,h[20];
memset(h,0,sizeof(h));
while (w){ h[w%10]++; w/=10; }
for (int j=0; j<10; j++)
if (h[j]>2) flag=0;
ans+=flag;
return ans;
}
LL gao0(int n){
int h[10],ans=0;
for (int i=1; i<=n; i++){
int t=i;
memset(h,0,sizeof(h));
while (t){ h[t%10]++; t/=10; }
int flag=1;
for (int j=0; j<10; j++)
if (h[j]>2) flag=0;
ans+=flag;
}
return ans;
}
int main(){
freopen("exchange.in","r",stdin);
freopen("exchange.out","w",stdout);
scanf("%I64d%I64d",&l,&r);
//cin >> l >> r ;
comb();
f[0]=1;
for (int i=1; i<=18; i++) f[i]=f[i-1]*i;
for (int i=0; i<10; i++) v[i]=2;
LL a1=gao(r);
for (int i=0; i<10; i++) v[i]=2;
LL a2=gao(l-1);
//cout << a1-a2 << endl;
printf("%I64d\n",a1-a2);
/*for (int j=500; j<=20000; j++){
for (int i=0; i<10; i++) v[i]=2;
if (gao(j)!=gao0(j)) cout << j<< endl;
}
for (int i=0; i<10; i++) v[i]=2;
*/
//cout << gao(1000)-gao(0) << endl;
//cout << a1-a2 << endl;
//cout << gao(1e18) << endl;
//cout << gao(555555) << endl;
//cout << gao(125545555) << endl;
//cout << gao0(125545555) << endl;
return 0;
}
}}}
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
typedef pair <int, int> PII;
const int INF=1e8, MN=1e6+7;
LL l,r,f[30],v[30];
LL C[40][40];
void comb(){
C[0][0]=1;
for (int i=1; i<=20; i++){
C[i][0]=1;
for (int j=1; j<i; j++)
C[i][j]=C[i-1][j-1]+C[i-1][j];
C[i][i]=1;
}
}
LL A(int n,int m){
LL ans=1;
for (LL i=n-m+1; i<=n; i++) ans*=i;
return ans;
}
LL calc(int k0){
int i,j,k=k0,n=0,m=0;
for (i=0; i<10; i++)
if (v[i]>0){
n++;
m+=v[i]==2;
}
LL ans=0;
for (i=0; i<=m && k>=0; i++,k-=2){
LL tmp=A(n-i,k)*C[m][i];
for (j=k+2; j<=k0; j+=2) tmp*=C[j][2];
ans+=tmp;
}
return ans;
}
LL gao(LL s){
if (s==0) return 0;
LL w=s;
int t[30]={};
while (s){ t[++t[0]]=s%10; s/=10; }
int i,j;
LL ans=0;
v[0]--;
for (i=t[0]-1; i>=2; i--){
ans+=calc(i-1)*9ll;
}
v[0]++;
if (t[0]>1) ans+=9;
for (i=t[0]; i>=1; i--){
for (j=(i==t[0])?1:0; j<t[i]; j++) if (v[j]>0){
v[j]--;
ans+=calc(i-1);
v[j]++;
}
if (--v[t[i]]<0) break;
}
/* int flag=1;
for (i=1; i<=t[0]; i++)
if (v[i]<0) flag=0;
*/
int flag=1,h[20];
memset(h,0,sizeof(h));
while (w){ h[w%10]++; w/=10; }
for (int j=0; j<10; j++)
if (h[j]>2) flag=0;
ans+=flag;
return ans;
}
LL gao0(int n){
int h[10],ans=0;
for (int i=1; i<=n; i++){
int t=i;
memset(h,0,sizeof(h));
while (t){ h[t%10]++; t/=10; }
int flag=1;
for (int j=0; j<10; j++)
if (h[j]>2) flag=0;
ans+=flag;
}
return ans;
}
int main(){
freopen("exchange.in","r",stdin);
freopen("exchange.out","w",stdout);
scanf("%I64d%I64d",&l,&r);
//cin >> l >> r ;
comb();
f[0]=1;
for (int i=1; i<=18; i++) f[i]=f[i-1]*i;
for (int i=0; i<10; i++) v[i]=2;
LL a1=gao(r);
for (int i=0; i<10; i++) v[i]=2;
LL a2=gao(l-1);
//cout << a1-a2 << endl;
printf("%I64d\n",a1-a2);
/*for (int j=500; j<=20000; j++){
for (int i=0; i<10; i++) v[i]=2;
if (gao(j)!=gao0(j)) cout << j<< endl;
}
for (int i=0; i<10; i++) v[i]=2;
*/
//cout << gao(1000)-gao(0) << endl;
//cout << a1-a2 << endl;
//cout << gao(1e18) << endl;
//cout << gao(555555) << endl;
//cout << gao(125545555) << endl;
//cout << gao0(125545555) << endl;
return 0;
}