Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //bluishgreen
- #pragma GCC optimize("-O3")
- #include <bits/stdc++.h>
- #include <sstream>
- #include<ctime>
- using namespace std;
- #define REP(i,a,b) for(i=a;i!=b;i++)
- #define getarr(a,n) for(i=0;i<n;i++){cin>>a[i];}
- #define disparr(a,n) for(i=0;i<n;i++){cout<<a[i];}cout<<"\n";
- #define disparrs(a,n) for(i=0;i<n;i++){cout<<a[i]<<" ";}cout<<"\n";
- #define disparrl(a,n) for(i=0;i<n;i++){cout<<a[i]<<"\n";}cout<<"\n";
- #define mem0(a) memset(a,0,sizeof(a));
- #define ll long long int
- #define ld long double
- #define key pair<ld,ld>
- #define pll pair<ll,ll>
- #define pii pair<int,int>
- #define si set<int>
- #define vii vector<pair<int,int> >
- #define vi vector<int>
- #define vll vector<ll>
- #define vb vector<bool>
- #define vvi vector<vector<int>>
- #define vs vector<string>
- #define all(v) v.begin(),v.end()
- #define pb push_back
- #define pob pop_back
- #define pof pop_front
- #define mp make_pair
- #define F first
- #define S second
- #define M 1000000007
- #define mul(x,y) ((ll)(x)*(y))%M
- #define tr(c,i) for(auto i = (c).begin(); i != (c).end(); i++)
- #define fastio ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
- #define INF 0x3f3f3f3f
- int MOD(int a, int b)
- {
- if(a>b)
- return a-b;
- else
- return b-a;
- }
- ll max3(ll a,ll b,ll c)
- {
- return max(c,max(a,b));
- }
- ll power(ll x,ll y, ll p)
- {
- ll res = 1;
- x = x % p;
- while (y > 0)
- {
- if (y & 1)
- res = (res*x) % p;
- y = y>>1;
- x = (x*x) % p;
- }
- return res;
- }
- ll max(ll a,ll b)
- {
- return (a>b)?a:b;
- }
- ll min(ll a,ll b)
- {
- return (a<b)?a:b;
- }
- ll gcd(ll a,ll b)
- {
- if(b==0)
- return a;
- else
- return gcd(b,a%b);
- }
- ll gcd_ext(ll a,ll b,ll &x, ll &y)//solves a*x+b*y=gcd(a,b)
- {
- if(b==0)
- {
- x=1;
- y=0;
- return a;
- }
- else
- {
- ll tmp,x1,y1;
- tmp = gcd_ext(b,a%b,x1,y1);//stores the result to b*x1+(a%b)*y1=gcd(b,a%b)=gcd(a,b)
- x = y1;
- y = x1 - (a/b)*y1;
- return tmp;
- }
- }
- class Solution {
- private:
- int nPr[11][11];
- int permute(int n,int r)
- {
- if(n < 0)
- return 0;
- return nPr[n][r];
- }
- public:
- Solution()
- {
- /*We precompute the values of nPr using dp,making use of the property:
- P(n,r) = P(n-1,r) + r * P(n-1,r-1).
- This is quite easy to derive and prove.*/
- int i,j;
- for(i = 0;i <= 10;i++)
- {
- for(j = 0;j <= 10;j++)
- {
- if(j == 0)
- nPr[i][j] = 1;//base case
- else if(i < j)
- nPr[i][j] = 0;
- else
- {
- nPr[i][j] = nPr[i-1][j]+ j * nPr[i-1][j-1];
- }
- }
- }
- }
- int numDupDigitsAtMostN(int N)
- {
- //This function computes f(N) as described in the editorial.
- if(N == 0 || N == 1)
- return 0;//base case
- int i,j;
- string a = to_string(N);//converting the number to a string makes processing easier.
- int ans = N;
- int n = a.size();//length of the number
- map<char,int> m;///this map is used to check if N itself can be used in the count.
- for(auto it: a)
- m[it]++;
- if(m.size() == n)
- ans--;//if the number N itself has no repeated digits, subtract it.
- map<char,bool> m1;//m1 stores the original digits appearing in the positions 0,1,...i-1 at the ith iteration.
- for(i = 0;i < n; i++)
- {
- int len = n-i-1;
- map<char,bool> av;//stores the set of available digits to be used in the positions ahead of i.
- for(j = 0;j < 10;j++)
- av[(char)(j+48)] = true;//initially add all digits to the map.
- for(auto it: m1)
- av.erase(it.first);
- int x = av.size(); //this is the number of numbers that can be used in positons (i+1,...n-1).
- for(j = a[i];j <= 57;j++)
- av.erase(j);//remove those digits that are greater than or equal to the current digit.
- // av now contains those digits that can be used at the current position.
- if(m1.size() == i)//no repeated digits already exist in previous indices, thus proceed to reduce the value of ans.
- {
- for(auto it: av)
- {
- if(i == 0 && it.first == 48)
- {
- /*This is the special case where the most significant digit of the number is 0. The proof of the formula
- being used here is left an an exercise for the reader.*/
- for(j = 1; j <= len; j++)
- ans -= permute(x,j) - permute(x-1,j-1);
- }
- else
- ans -= permute(x-1,len);
- }
- }
- m1[a[i]] = true;
- }
- return ans;
- }
- };
- int main()
- {
- fastio;
- int t;
- cin>>t;
- Solution* obj = new Solution();
- while(t--)
- {
- int a,b;
- cin>>a>>b;
- int ans = obj->numDupDigitsAtMostN(b) - obj->numDupDigitsAtMostN(a-1);
- cout<<ans<<'\n';
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment