QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#735836 | #2519. Number with Bachelors | CSQ | AC ✓ | 188ms | 146304kb | C++17 | 6.2kb | 2024-11-11 22:00:27 | 2024-11-11 22:00:27 |
Judging History
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