题解 叮叮车

传送门

就是 Catalan 数,求 \([l, r]\)\(C_i\)\(p\) 的幂次最大值
那么库默尔定理\(\binom{n+m}{n}\)\(p\) 的幂次就是 \(n+m\)\(p\) 进制下的进位次数
那么要最大化这个东西,可以放到 7 进制下贪心
找到 \(l, r\) 的最高不同位,找到接下来的一段连续进位串
选最高位的 \(>3\) 的,如果没有选最高的 3
将这位 -1,后面的全填 6 即可

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 1000010
#define pb push_back
#define ll long long
#define int long long

const ll mod=1e9+7;
int tl[N], tr[N], tem[N], tot, now;

struct Int{
	int base;
	vector<int> a;
	Int(){base=678223072849;}
	Int(int t){base=678223072849; do {a.pb(t%base); t/=base;} while (t);}
	int len() {return a.size();}
	inline int& operator [] (int t) {return a[t];}
	void adjust() {while (a.size()>1&&!a.back()) a.pop_back();}
	void print() {for (int i=a.size()-1; ~i; --i) printf("%lld", a[i]); printf("\n");}
	void scan() {
		a.clear();
		vector<int> tem[2];
		int now=0; char c=getchar();
		while (!isdigit(c)) c=getchar();
		int lst=0, cnt=0;
		while (isdigit(c)) {tem[now].pb(c-'0'); c=getchar();}
		for (; ; now^=1) {
			// cout<<"tem: "; for (auto it:tem[now]) cout<<it<<' '; cout<<endl;
			for (auto it:tem[now]) if (it) goto jump; break; jump:
			tem[now^1].clear();
			ll rest=0; bool any=0;
			for (auto it:tem[now]) {
				rest=rest*10+it;
				if (rest/base||any) tem[now^1].pb(rest/base);
				if (rest/base) any=1;
				rest%=base;
			}
			a.pb(rest);
		}
		adjust();
		if (!a.size()) a.pb(0);
	}
	inline Int operator + (Int b) {
		Int ans;
		int lim=max(len(), b.len())+2;
		ans.a.resize(lim);
		for (int i=0; i<lim-1; ++i) {
			if (i<len()) ans[i]+=a[i];
			if (i<b.len()) ans[i]+=b[i];
			ans[i+1]+=ans[i]/base;
			ans[i]%=base;
		}
		ans.adjust();
		return ans;
	}
	inline Int operator * (Int b) {
		Int ans; ans.a.resize(len()+b.len()+1);
		for (int i=0; i<len(); ++i)
			for (int j=0; j<b.len(); ++j) {
				ans[i+j]=ans[i+j]+a[i]*b[j];
				ans[i+j+1]+=ans[i+j]/base;
				ans[i+j]%=base;
			}
		ans.adjust();
		return ans;
	}
	inline Int operator - (Int b) {
		Int ans=*this;
		for (int i=0; i<b.len(); ++i) ans[i]-=b[i];
		for (int i=0; i<len(); ++i)
			if (ans[i]<0) --ans[i+1], ans[i]+=base;
		ans.adjust();
		return ans;
	}
	inline Int operator / (int b) {
		Int ans; ans.a.resize(len());
		ll rest=0;
		for (int i=len()-1; ~i; --i) {
			rest=rest*base+a[i];
			ans[i]=rest/b; rest%=b;
		}
		ans.adjust();
		return ans;
	}
	inline ll toint() {
		ll ans=0;
		for (int i=a.size()-1; ~i; --i) ans=(ans*base+a[i])%mod;
		return ans;
	}
	inline bool operator <= (Int b) {
		if (len()!=b.len()) return len()<b.len();
		for (int i=len()-1; ~i; --i)
			if (a[i]!=b[i]) return a[i]<b[i];
		return 1;
	}
	inline bool operator < (Int b) {
		if (len()!=b.len()) return len()<b.len();
		for (int i=len()-1; ~i; --i)
			if (a[i]!=b[i]) return a[i]<b[i];
		return 0;
	}
	bool notzero() {return a.size()>1||a[0]!=0;}
}l, r, ans;

inline Int f(Int n) {
	Int ans(0); while (n.notzero()) n=n/7, ans=ans+n;
	return ans;
}

signed main()
{
	freopen("dingdingcar.in", "r", stdin);
	freopen("dingdingcar.out", "w", stdout);
	
	l.scan(); r.scan();
	// l.print(); r.print();
	l.a.resize(r.len());
	ans.a.resize(r.len());
	// for (int i=r.len()-1; ~i; --i) {
	// 	if (l[i]==r[i]||!i) ans[i]=r[i];
	// 	else {
	// 		ans[i]=r[i]-1;
	// 		for (int j=i-1; ~j; --j) ans[j]=6;
	// 		break;
	// 	}
	// }
	// ans.print();
	// ll cnt=0;
	// ans.a.resize(ans.len()+1);
	// for (int i=0,lim=ans.len(); i+1<lim; ++i)
	// 	if (ans[i]>3) ++cnt, ++ans[i+1];
	// cout<<cnt<<endl;
	for (int i=0,lim=l.len(); i<lim; ++i) {
		int t=l[i];
		for (int j=1; j<=14; ++j)
			tl[++tot]=t%7, t/=7;
	}
	for (int i=0,lim=r.len(); i<lim; ++i) {
		int t=r[i];
		for (int j=1; j<=14; ++j)
			tr[++now]=t%7, t/=7;
	}
	// cout<<"tl: "; for (int i=1; i<=tot; ++i) cout<<tl[i]<<' '; cout<<endl;
	// cout<<"tr: "; for (int i=1; i<=tot; ++i) cout<<tr[i]<<' '; cout<<endl;
	for (int i=tot; i; --i) {
		if (tl[i]==tr[i] || i==1) tem[i]=tr[i];
		else {
			// cout<<"i: "<<i<<endl;
			if (tr[i]!=3) {
				tem[i]=tr[i]-1;
				for (int j=i-1; j; --j) tem[j]=6;
			}
			else {
				int pos1=i, pos2=i-1;
				while (pos2 && tr[pos2]>=3) {
					if (tr[pos2]>3) pos1=pos2;
					--pos2;
				}
				int maxi=i;
				for (int j=pos1; j<=i; ++j) if (tr[j]>3) maxi=j;
				for (int j=i; j>=pos1; --j) tem[j]=tr[j];
				tem[maxi]=tr[maxi]-1;
				for (int j=maxi-1; j; --j) tem[j]=6;
				// cout<<"maxi: "<<maxi<<endl;
			}
			break;
		}
	}
	for (int i=r.len()-1; ~i; --i) {
		int t=0;
		for (int j=1; j<=14; ++j)
			t=t*7+tem[tot--];
		ans[i]=t;
	}
	// cout<<"tot: "<<tot<<endl;
	// cout<<max((f(r*Int(2))-Int(2)*f(r)).toint(), (f(ans*Int(2))-Int(2)*f(ans)).toint())<<endl;
	cout<<(f(ans*Int(2))-Int(2)*f(ans)).toint()<<endl;

	return 0;
}
posted @ 2022-04-05 18:54  Administrator-09  阅读(3)  评论(0编辑  收藏  举报