QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#591145#2519. Number with BachelorsCSQTL 62ms142092kbC++234.7kb2024-09-26 14:28:442024-09-26 14:28:46

Judging History

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

  • [2024-09-26 14:28:46]
  • 评测
  • 测评结果:TL
  • 用时:62ms
  • 内存:142092kb
  • [2024-09-26 14:28:44]
  • 提交

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 unsigned long long int ll;
typedef pair<int,int> pii;
typedef vector<int> vi;

ll dp[11][11][1024]; //if I have i digits left and mask denotes the digit used, how many assignments?
ll hp[17][17][65536];
ll P[20][20];
ll find(ll n){
    if(n == 0)return 1;
    vector<int>v;
    while(n){
        v.push_back(n%10);
        n/=10;
    }
    reverse(all(v));
    n = sz(v);

    ll ans = 1;
    int mask = 0;
	for(int i=1;i<n;i++)ans += P[10][i] - P[9][i-1];
    for(int i=0;i<n;i++){
		if(!i){
			if(v[i]>1){
				ans += dp[v[i]-1][n][mask];
				//cout<<dp[v[i]-1][n][mask]<<'\n';
			}
		}else if(v[i]){
			ans += dp[v[i]-1][n][mask];
			//cout<<dp[v[i]-1][n][mask]<<'\n';
		}

		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 1;
    vector<int>v;
    while(n){
        v.push_back(n%16);
        n/=16;
    }
    reverse(all(v));
    n = sz(v);

    ll ans = 1;
    int mask = 0;
	for(int i=1;i<n;i++)ans += P[16][i] - P[15][i-1];
    for(int i=0;i<n;i++){
		if(!i){
			if(v[i]>1){
				ans += hp[v[i]-1][n][mask];
				//cout<<dp[v[i]-1][n][mask]<<'\n';
			}
		}else if(v[i]){
			ans += hp[v[i]-1][n][mask];
			//cout<<dp[v[i]-1][n][mask]<<'\n';
		}

		if(mask & (1<<v[i]))break;
		mask |= (1<<v[i]);
		if(i==n-1)ans++;
    }
    return ans;
}
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;
}
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;
        }
    }
	//dp[i][len][mask] = if mask is used, my number has len digits and the next digit is <= i how many ways to make the number?
    for(int mask=0;mask<(1<<10);mask++){
        int ch = __builtin_popcount(mask);
		if(ch != 10){
			for(int len = ch;len <= 10;len++){
				ll run = 0;
				for(int i=(mask==0);i<10;i++){
					if(!(mask&(1<<i)))run += P[10-ch-1][len-ch-1];
					dp[i][len][mask] = run;
				}
			}
		}
    }
    for(int mask=0;mask<(1<<16);mask++){
        int ch = __builtin_popcount(mask);
		if(ch != 16){
			for(int len = ch;len <= 16;len++){
				ll run = 0;
				for(int i=(mask==0);i<16;i++){
					if(!(mask&(1<<i)))run += P[16-ch-1][len-ch-1];
					hp[i][len][mask] = run;
				}
			}
		}
    }
    int t;
    cin>>t;
    while(t--){
        char c;
        int mode;
        cin>>c>>mode;
        if(c == 'd'){
            if(!mode){
                ll a,b;
                cin>>a>>b;
                if(a==0)cout<<find(b)<<'\n';
                else cout<<find(b)-find(a-1)<<'\n';
            }else{
                ll n;
                cin>>n;
                ll l = 0,r = 1e11;
                while(r>=l){
                    ll mid = (l+r)/2;
                    //cout<<mid<<" "<<find(mid)<<'\n';
                    if(find(mid) >= n)r = mid-1;
                    else l = mid+1;
                }
                if(find(l) != n)cout<<"-"<<'\n';
                else cout<<l<<'\n';
            }
        }else{
            if(!mode){
                string s0,s1;
                cin>>s0>>s1;
                ll a = condec(s0),b = condec(s1);
                ll ans = 0;
                if(a==0)ans = find2(b);
                else ans = find2(b) - find2(a-1);
                cout<<conhex(ans)<<'\n';
            }else{
                string s0;
                cin>>s0;
                ll n = condec(s0);
                //cout<<s0<<" "<<n<<'\n';
                ll l = 0,r = 1e17;
                while(r>=l){
                    ll mid = (l+r)/2;
                    //cout<<mid<<" "<<find(mid)<<'\n';
                    if(find2(mid) >= n)r = mid-1;
                    else l = mid+1;
                }
                if(find2(l) != n)cout<<"-"<<'\n';
                else cout<<conhex(l)<<'\n';
            }

        }
    }

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

详细

Test #1:

score: 100
Accepted
time: 62ms
memory: 142092kb

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: -100
Time Limit Exceeded

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:


result: