QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#735836#2519. Number with BachelorsCSQAC ✓188ms146304kbC++176.2kb2024-11-11 22:00:272024-11-11 22:00:27

Judging History

你现在查看的是最新测评结果

  • [2024-11-11 22:00:27]
  • 评测
  • 测评结果:AC
  • 用时:188ms
  • 内存:146304kb
  • [2024-11-11 22:00:27]
  • 提交

answer

//#pragma GCC target ("avx2")
//#pragma GCC optimization ("O3")
//#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>
using namespace std;

#define rep(i,a,b) for(int i=a;i<b;++i)
#define all(x) begin(x),end(x)
#define sz(x) (int)(x).size()
typedef uint64_t ll;
typedef pair<int,int> pii;
typedef vector<int> vi;

ll dp[11][11][1024]; //if used numbers are in mask, I have i digits left to fill and the next digit <= i, how many ways
ll hp[17][17][65536];
ll dn[11],hn[17];
ll P[20][20];

ll condec(string s0){
    ll a = 0;
    for(ll i=sz(s0)-1,j=1;;i--){
        if(s0[i]>='a' && s0[i]<='f')a += j * (s0[i]-'a'+10);
        else a += j * (s0[i]-'0');
        j*=16;
        if(i==0)break;
    }

    return a;
}
string conhex(ll n){
    if(n==0)return "0";
    string s;
    while(n){
        int r = n%16;
        if(r<=9)s.push_back(r + '0');
        else s.push_back(r-10+'a');
        n/=16;
    }
    reverse(all(s));
    return s;
}
ll limd = 8877693;
ll limh = 53319412081141;
ll find(ll n){
	if(n<0)return 0;
	if(n==0)return 1;
	vector<int>v;
	while(n){
		v.push_back(n%10);
		n/=10;
	}
	reverse(all(v));
	int mask = 0;
	n = sz(v);
	if(n>10){
		v.resize(10);
		n = 10;
		for(int i=0;i<10;i++)v[i] = 9;
	}
	ll ans = dn[n-1];
	if(n==1)ans++;
	for(int i=0;i<n;i++){
		if(v[i])ans += dp[v[i]-1][n-i][mask];
		if(mask & (1<<v[i]))break;
		mask += 1<<v[i];
		if(i == n-1)ans++;
	}
	return ans;
}

ll find2(ll n){
	if(n<0)return 0;
	if(n==0)return 1;
	vector<int>v;
	while(n){
		v.push_back(n%16);
		n/=16;
	}
	reverse(all(v));
	int mask = 0;
	n = sz(v);
	if(n>16){
		v.resize(16);
		n = 16;
		for(int i=0;i<16;i++)v[i] = 16;
	}
	ll ans = hn[n-1];
	if(n==1)ans++;
	for(int i=0;i<n;i++){
		if(v[i])ans += hp[v[i]-1][n-i][mask];
		if(mask & (1<<v[i]))break;
		mask += 1<<v[i];
		if(i == n-1)ans++;
	}
	return ans;
}
int brute(int n,int b){
	int ans = 1;
	for(int i=1;i<=n;i++){
		bool ok = 1;
		int j = i;
		vector<bool>seen(b,0);
		while(j){
			if(seen[j%b])ok = 0;
			seen[j%b] = 1;
			j/=b;
		}
		ans	+= ok;
	}
	return ans;
}
int check(int n,int b){
	for(int i=0;;i++){
		bool ok = 1;
		int j = i;
		vector<bool>seen(b,0);
		while(j){
			if(seen[j%b])ok = 0;
			seen[j%b] = 1;
			j/=b;
		}
		n-=ok;
		if(!n)return i;
	}
}
int main()
{
   cin.tie(0)->sync_with_stdio(0);
   cin.exceptions(cin.failbit);
    P[0][0] = 1;
    for(int i=0;i<=16;i++){
        P[i][0] = 1;
        ll f = 1;
        for(int j=i;j>=1;j--){
            f *= j;
            P[i][i-j+1] = f;
        }
    }
	for(int i=1;i<=10;i++)dn[i] = dn[i-1] + P[10][i] - P[9][i-1];
	for(int i=1;i<=10;i++)dn[i]++;
	for(int mask=0;mask<(1<<10);mask++){
		int ch = __builtin_popcount(mask);
		for(int len=0;len<=10-ch;len++){
			for(int i=0;i<10;i++){
				if(!len){
					dp[i][len][mask] = 1;
					continue;
				}
				int cnt = 0;
				for(int j=0;j<=i;j++)cnt +=  (mask & (1<<j)) == 0;
				if(!cnt)continue;
				if(!ch){
					if(mask&1)dp[i][len][mask] += cnt * (P[10-ch-1][len-1]);	
					else dp[i][len][mask] += (cnt-1) * (P[10-ch-1][len-1]);	
				}
                else dp[i][len][mask] += cnt * (P[10-ch-1][len-1]);			
			}
		}
	}
	for(int i=1;i<=16;i++)hn[i] = hn[i-1] + P[16][i] - P[15][i-1];
	for(int i=1;i<=16;i++)hn[i]++;
	for(int mask=0;mask<(1<<16);mask++){
		int ch = __builtin_popcount(mask);
		for(int len=0;len<=16-ch;len++){
			for(int i=0;i<16;i++){
				if(!len){
					hp[i][len][mask] = 1;
					continue;
				}
				int cnt = 0;
				for(int j=0;j<=i;j++)cnt +=  (mask & (1<<j)) == 0;
				if(!cnt)continue;
				if(!ch){
					if(mask&1)hp[i][len][mask] += cnt * (P[16-ch-1][len-1]);	
					else hp[i][len][mask] += (cnt-1) * (P[16-ch-1][len-1]);	
				}
                else hp[i][len][mask] += cnt * (P[16-ch-1][len-1]);			
			}
		}
	}
	limd = find(100000000000);
	limh = find2(100000000000000000);
	//cout<<limh<<" "<<limd<<'\n';
	//for(int i=1;i<=10000;i++)assert(brute(i,10) == find(i));
	//for(int i=1;i<=10000;i++)assert(brute(i,16) == find2(i));
    int t;
    cin>>t;
	for(int tc=1;tc<=t;tc++){
        char c;
        int mode;
        cin>>c>>mode;
        if(c == 'd'){
			if(!mode){
				ll a,b;
				cin>>a>>b;
				ll ans = find(b);
				if(a)ans -= find(a-1);
				cout<<ans<<'\n';
			}else{
				ll n;
				cin>>n;
				if(n==1){
					cout<<0<<'\n';
					continue;
				}
				if(n>limd){
					cout<<"-"<<'\n';
					continue;
				}
				//cout<<check(n,10)<<'\n';
				
				ll cnt = 1;
				int len = 1;
				while(dn[len] < n)len++;
				int mask = 0;
				
				if(len)n -= dn[len-1];
				if(len==1)n--;
				//cout<<n<<" "<<len<<'\n';
				vector<int>ans;
				for(int i=len;i>=1;i--){
					ans.push_back(0);
					ll run = 0;
					ll last = 0;
					for(int j=0;j<=9;j++){
						if(mask & (1<<j))continue;
						if(i == len && j == 0)continue;
						if(n > run){
							ans.back() = j;
							last = run;
						}else break;
						run += dp[9][i-1][mask + (1<<j)];
					}
					n -= last;
					mask += (1<<ans.back());
				}
				for(int x:ans)cout<<x;
				cout<<'\n';
			}
		}else{
			if(!mode){
				string a,b;
				cin>>a>>b;
				ll B = condec(b);
				ll A = condec(a);
				ll ans = find2(B);
				if(A)ans -= find2(A-1);
				cout<<conhex(ans)<<'\n';
			}else{
				string s;
				cin>>s;
				ll n = condec(s);
				if(n==1){
					cout<<0<<'\n';
					continue;
				}
				if(n>limh){
					cout<<"-"<<'\n';
					continue;
				}
				//cout<<conhex(check(n,16))<<'\n';
				ll cnt = 1;
				int len = 1;
				while(hn[len] < n)len++;
				int mask = 0;
				
				if(len)n -= hn[len-1];
				if(len==1)n--;
				
				vector<int>ans;
				for(int i=len;i>=1;i--){
					ans.push_back(0);
					ll run = 0;
					ll last = 0;
					for(int j=0;j<=15;j++){
						if(mask & (1<<j))continue;
						if(i == len && j == 0)continue;
						if(n > run){
							ans.back() = j;
							last = run;
						}else break;
						run += hp[15][i-1][mask + (1<<j)];
					}
					n -= last;
					mask += (1<<ans.back());
				}
				
				for(int x:ans){
					if(x<=9)cout<<x;
					else cout<<char('a' + x-10);
				}
				cout<<'\n';
				
			}
			
			
		}
    }

}
/*
6
d 0 10 20
h 0 10 1f
d 1 10
h 1 f
d 1 1000000000
h 1 ffffffffffffffff
*/

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 142ms
memory: 146304kb

input:

6
d 0 10 20
h 0 10 1f
d 1 10
h 1 f
d 1 1000000000
h 1 ffffffffffffffff

output:

10
f
9
e
-
-

result:

ok 6 lines

Test #2:

score: 0
Accepted
time: 188ms
memory: 143600kb

input:

50000
h 1 147a
d 0 25 71
d 1 3587
d 0 26922 51887
d 1 711
d 0 3 5
h 0 7bf2defab442a0b1 f299a4cf1d4d9bed
d 0 6961 91018
d 1 4
d 1 876
h 1 12cc5d3370f99120
d 1 161315
h 0 25f 6959
d 0 467 516
d 1 298
h 1 70260cdc2da73281
h 1 928e17d65d764ca2
h 1 c8ec8a7b67605e51
d 1 91697
d 0 4941925161850941148 89850...

output:

1b36
43
6587
7710
953
3
8daab378500
26054
3
1356
-
946307
4681
40
387
-
-
-
491850
0
1
29
-
4605298
1
1
-
15b4
175f
9b944134000
124b7
6279
9
6257
-
39be22a900
5c636b59300
146ce
2a55
-
0
-
7
d
6
2041
-
1c94afe7300
0
5
9149
16540973
1389
125
0
-
3bc31189480
424
66800
7
-
-
1e6
0
0
48b6
9
-
2b0
5019
14...

result:

ok 50000 lines