2020CCPC威海站部分题解

A题

首先第一步是把所有人都移动到另一侧。

然后就是等待缓冲时间,需要分类讨论,手动模拟一下即可找到规律。

最后一步就是把所有人都移动到初始侧。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 

int main()
{
    ios ;
    int T ;
    cin >> T ;
    while(T --)
    {
        ll n , x , t ;
        cin >> n >> x >> t ;
        ll ans = 0 ;
        ans += 4 * n * t ;
        if(x > 2 * (n - 1) * t)  
        {
            ll res = 0 ;
            res += 2 * n * t + t ;
            if(res - t < x)  res = t + x - (res - t) ;
            else  res = t ;
            ans += min(res , x - 2 * (n - 1) * t) ;
        }
        cout << ans << '\n' ;
    }
    return 0 ;
}

C题

参考dalao

想到公式后,很裸的换根dp。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
int n ;
vector<pii> g[maxn] ;
bool vis[maxn] ;
ll dp[maxn][3] ;
int cnt[maxn] ;
int siz[5] ;
vector<int> c[3] ;
void dfs1(int fa , int u , int id)
{
    cnt[u] += vis[u] ;
    for(auto x : g[u])
    {
        int v = x.fi ;
        int w = x.se ;
        if(v == fa)  continue ;
        dfs1(u , v , id) ;
        cnt[u] += cnt[v] ;
        dp[u][id] += dp[v][id] + 1ll * cnt[v] * w ;
        //if(u == 1 && id == 2)  ddebug(dp[v][id] , 1ll * cnt[v] * w) ;
    }
}
void dfs2(int fa , int u , int id)
{
    for(auto x : g[u])
    {
        int v = x.fi ;
        int w = x.se ;
        if(v == fa)  continue ;
        dp[v][id] += (dp[u][id] - dp[v][id] - 1ll * cnt[v] * w) + 1ll * (cnt[1] - cnt[v]) * w ;
        dfs2(u , v , id) ;
    }
}
int main()
{
    ios ;
    cin >> n ;
    rep(i , 1 , n - 1)
    {
        int u , v , w ;
        cin >> u >> v >> w ;
        g[u].pb({v , w}) ;
        g[v].pb({u , w}) ;
    }
    rep(i , 0 , 2)
    {
        int k ;
        cin >> k ;
        siz[i] = k ;
        mem0(vis) ;
        mem0(cnt) ;
        rep(j , 1 , k)
        {
            int x ;
            cin >> x ;
            vis[x] = 1 ;
            c[i].pb(x) ;
        }
        dfs1(1 , 1 , i) ;
        dfs2(1 , 1 , i) ;
    }
    db ans = 0 ;
    for(auto x : c[0])  ans += dp[x][1] * siz[2] ;
    for(auto x : c[0])  ans += dp[x][2] * siz[1] ;
    for(auto x : c[1])  ans += dp[x][2] * siz[0] ;
    ans /= 2 ;
    ans /= siz[0] ;
    ans /= siz[1] ;
    ans /= siz[2] ;
    cout << fixed << setprecision(15) << ans << '\n' ;
    return 0 ;
}

D题

不是很会证明,打个表规律全出来了。

把c质因数分解,如果每个质数的指数都是1,那就输出no。

然后考虑怎么判断c可以整除某个质数的平方。

数据范围写着时间复杂度是O(c^{\frac{1}{3}})。手推一下就可以判断了。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
struct Easymath
{
    ll qpow(ll a , ll b) //快速幂
    {
        if(b < 0)  return 0 ;
        ll ans = 1 ; 
        a %= mod ;
        while(b)
        {
            if(b & 1)  ans = (ans * a) % mod ;
            b >>= 1 , a = (a * a) % mod ;
        }
        return ans % mod ;
    }
    ll ksc_log(ll x , ll y , ll mod) //快速乘
    {
        x %= mod , y %= mod ;
        ll ans = 0;
        while(y)
        {
            if(y & 1) ans = (ans + x) % mod ; 
            y >>= 1 ;
            x = (x + x) % mod ;
        }
        return ans;
    }
    ll ksc_O1(ll x , ll y , ll mod) //快速乘
    {
        x %= mod , y %= mod ;
        ll z = (ld)x * y / mod ;
        ll ans = x * y - z * mod ;
        if(ans < 0)  ans += mod ;
        else if(ans >= mod)  ans -= mod ;
        return ans ;
    }
    int cnt = 0 ;
    bool vis[maxn] ;
    int prime[maxn] ;
    void get_prime(int up) //素数筛
    {
        memset(vis , 0 , sizeof(vis)) ;
        vis[1] = 1 ;
        for(int i = 2 ; i <= up ; i ++)
        {
            if(!vis[i]) 
            prime[++ cnt] = i ;
            for(int j = 1 ; j <= cnt && i * prime[j] <= up ; j ++)
            {
                vis[i * prime[j]] = 1 ;
                if(i % prime[j] == 0) break ;
            }
        }
    }
    //begin 判定大素数
    ll mul(ll a , ll b , ll mod)
    {
        ll ret = 0 ;
        while(b) 
        {
            if(b & 1)  ret = (ret + a) % mod ;
            a = (a + a) % mod ;
            b >>= 1 ;
        }
        return ret ;
    }
    ll pow(ll a , ll b , ll mod)
    {
        ll ret = 1 ;
        while(b) 
        {
            if(b & 1)  ret = mul(ret , a , mod) ;
            a = mul(a , a , mod) ;
            b >>= 1 ;
        }
        return ret ;
    }
    bool check(ll a , ll n)
    {
        ll x = n - 1 ;
        int t = 0 ;
        while((x & 1) == 0) 
        {
            x >>= 1 ;
            t ++ ;
        }
        x = pow(a , x , n) ;
        ll y ;
        rep(i , 1 , t)
        {
            y = mul(x , x , n) ;
            if(y == 1 && x != 1 && x != n - 1)  return 1 ;
            x = y ;
        }
        if(y != 1) return 1 ;
        return 0 ;
    }
    bool Miller_Rabin(ll n) 
    {
        if(n == 2)  return 1 ;
        if(n == 1 || !(n & 1))  return 0 ;
        const int arr[12] = {2,3,5,7,11,13,17,19,23,29,31,37} ;
        rep(i , 0 , 11) 
        {
            if(arr[i] >= n) break ;
            if(check(arr[i] , n)) return 0 ;
        }
        return 1 ;
    }
    //end 判定大素数
    ll get_inv(ll x) //逆元
    {
       return qpow(x , mod - 2) % mod ;
    }
    ll inv1[maxn] ;  //乘法逆元
    void init1(int up)
    {
       inv1[1] = 1 ;
       for(int i = 2 ; i <= up ; i ++)
         inv1[i] = (ll)(mod - mod / i) * inv1[int(mod % (ll)i)] % mod ;
    }
    ll fac[maxn] ;
    ll inv[maxn] ; //阶乘逆元
    void init(int up) 
    {
       fac[0] = fac[1] = inv[0] = inv[1] = 1 ;
       for(int i = 2 ; i <= up ; i ++)
       {
         fac[i] = fac[i - 1] * i % mod ;
         inv[i] = -inv[mod % i] * (mod / i) % mod ;
         while(inv[i] < 0) inv[i] += mod ;
       }
       for(int i = 2 ; i <= up ; i ++)  
         inv[i] = inv[i] * inv[i - 1] % mod ;
    }
    ll C(int n , int m)
    {
        return fac[n] * inv[m] % mod * inv[n - m] % mod ;
    }
} em ;
void win()
{
    cout << "yes\n" ;
}
void lose()
{
    cout << "no\n" ;
}
int rad(int x)
{
    int res = 1 ;
    rep(i , 2 , x)  if(!em.vis[i] && x % i == 0)  res *= i ;
    return res ;
}
bool ok(int i)
{
    rep(j , 1 , i - 1)  if(rad(j * (i - j) * i) < i)  return 1 ;
    return 0 ;
}
void solve()
{
    ll n ;
    bool flag = 0 ;
    cin >> n ;
    rep(i , 2 , 1000000)  
    {
        ll tmp = 1ll * i * i * i ;
        if(tmp > n)  break ; 
        else if(n % tmp == 0)
        {
            flag = 1 ;
            break ;
        }
    }
    rep(i , 2 , 1000000)
    {
        ll tmp = 1ll * i * i ;
        if(tmp > n)  break ; 
        else if(n % tmp == 0)
        {
            flag = 1 ;
            break ;
        }
    }
    rep(i , 2 , 1000000)
    {
        if(i > n)  break ;
        while(n % i == 0)  n /= i ;
    }
    if(flag == 0 && n > 1)
    {
        ll tmp = sqrt(n + 0.5) ;
        if(tmp * tmp == n)  flag = 1 ;
    }
    if(flag)  win() ;
    else  lose() ;
}
int main()
{
    ios ;
    int T ;
    cin >> T ;
    while(T --)  solve() ;
    return 0 ;
}

G题

首先判断两个区间是否相同基本就是hash了。

区间加那就是线段树。

所以这题就是线段树hash。

因为有个取模操作,但是因为每次区间加1,所以每个数取模次数均摊下来不会很多,大约每个数取模10次。

可以树上二分,暴力点修改取模。记录个区间最大值就好了。 

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int maxn = 5e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ;
typedef unsigned long long ull ;
const ull mod = 21788233 ;
ull base = 131 ;
int a[maxn] ;
ull p[maxn] ;
ull pre[maxn] ;
struct seg_tree
{
	ull mx[maxn << 2] , add[maxn << 2] ;
	ull hash1[maxn << 2] ;
	int ls(int x)
	{
		return x << 1 ;
	}
	int rs(int x)
	{
		return x << 1 | 1 ;
	}
	void push_up(int id , int len)
	{
		mx[id] = max(mx[ls(id)] , mx[rs(id)]) ;
		hash1[id] = hash1[ls(id)] * p[len] + hash1[rs(id)] ;
		hash1[id] %= mod ;
	}
	void build(int id , int l , int r)
	{
		add[id] = 0 ;
		if(l == r)
		{
			mx[id] = hash1[id] = a[l] ;
			return ;
		}
		int mid = (l + r) >> 1 ;
		build(ls(id) , l , mid) ;
		build(rs(id) , mid + 1 , r) ;
		push_up(id , r - mid) ;
	}
	void f(int id , int l , int r , ll k)
	{
		add[id] = add[id] + k , add[id] %= mod;
		mx[id] = mx[id] + k  , mx[id] %= mod;
		hash1[id] = hash1[id] + k * pre[r - l] ;
		hash1[id] %= mod ;
	}
	void push_down(int id , int l , int r)
	{
		int mid = (l + r) >> 1 ;
		f(ls(id) , l , mid , add[id]) ;
		f(rs(id) , mid + 1 , r , add[id]) ;
		add[id] = 0 ;
	}
	void update(int id , int l , int r , int x , int y , ll k)
	{
		if(x > y || x > r || y < l)  return ; //±ÜÃâÔ½½ç¡£
		if(x <= l && r <= y)
		{
			mx[id] += k ;
			add[id] += k ;
			hash1[id] += pre[r - l] ;
			hash1[id] %= mod;
			return ;
		}
		push_down (id , l , r) ;
		int mid = (l + r) >> 1 ;
		if(x <= mid) update(ls(id) , l , mid , x , y , k) ;
		if(y > mid)  update(rs(id) , mid + 1 , r , x , y , k) ;
		push_up(id , r - mid) ;
	}
	ull query(int id , int l , int r , int x , int y)
	{
		if(x > y || x > r || y < l)  return 0 ; //±ÜÃâÔ½½ç¡£
		ull ans = 0 ;
		if(x <= l && r <= y) return hash1[id] ;
		int mid = (l + r) >> 1 ;
		push_down(id , l , r) ;
		if(y <= mid)  return query(ls(id) , l , mid , x , y) ;
		else if(mid + 1 <= x)  return query(rs(id) , mid + 1 , r , x , y) ;
		else
		{
			ans += query(ls(id) , l , mid , x , y) * p[min(r , y) - mid] ;
			ans += query(rs(id) , mid + 1 , r , x , y) ;
			return ans % mod ;
		}
	}
	void dfs(int id , int l , int r)
	{
		int mid = (l + r) >> 1 ;
		if(mx[id] < 65536)  return ;
		if(l == r)
		{
			hash1[id] = 0 ;
			mx[id] = 0 ;
			return ;
		}
		push_down(id , l , r) ;
		if(mx[ls(id)] == 65536)  dfs(ls(id) , l , mid) ;
		if(mx[rs(id)] == 65536)  dfs(rs(id) , mid + 1 , r) ;
		push_up(id , r - mid) ;
	}
} seg ;
int main()
{
	ios ;
	int n , q ;
	cin >> n >> q ;
	rep(i , 1 , n)  cin >> a[i] ;
	p[0] = 1 ;
	pre[0] = 1 ;
	for(int i = 1 ; i <= n ; i ++)  p[i] = p[i - 1] * 131 , p[i] %= mod ;
	for(int i = 1 ; i <= n ; i ++)  pre[i] = pre[i - 1] + p[i] , pre[i] %= mod ;
	seg.build(1 , 1 , n) ;
	while(q --)
	{
		int op ;
		cin >> op ;
		if(op == 1)
		{
			int l , r ;
			cin >> l >> r ;
			seg.update(1 , 1 , n , l , r , 1) ;
			seg.dfs(1 , 1 , n) ;
		}
		else
		{
			int x , y , L ;
			cin >> x >> y >> L ;
			ull h1 = seg.query(1 , 1 , n , x , x + L - 1) ;
			ull h2 = seg.query(1 , 1 , n , y , y + L - 1) ;
			if(h1 == h2)  cout << "yes\n" ;
			else  cout << "no\n" ;
		}
	}
	return 0 ;
}

H题

直接模拟就行了。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
int n , m , s ;
map<int , int> a[maxn] ;
int b[maxn] ;
int ans[maxn] ;
int main()
{
    ios ;
    cin >> m >> n >> s ;
    while(s --)
    {
        int t , x , y ;
        cin >> t >> x >> y ;
        if(t == 1)  a[x][y] = b[y] ;
        else if(t == 2)  
        {
            ans[x] += b[y] - a[x][y] ;
            a[x].erase(y) ;
        }
        else  ans[x] -- , b[y] ++ ;
    }
    rep(i , 1 , n)  for(auto x : a[i])  ans[i] += b[x.fi] - x.se ;
    rep(i , 1 , n)  cout << ans[i] << '\n' ;
    return 0 ;
}

L题

构造一个任意长度的序列a\sum a_i\leqslant b

最大化序列的lcm。

每个质数的幂次认为是一组,跑分组背包。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
db lg[maxn] ;
db dp[maxn] ;
struct Easymath
{
    ll qpow(ll a , ll b) //快速幂
    {
        if(b < 0)  return 0 ;
        ll ans = 1 ; 
        a %= mod ;
        while(b)
        {
            if(b & 1)  ans = (ans * a) % mod ;
            b >>= 1 , a = (a * a) % mod ;
        }
        return ans % mod ;
    }
    ll ksc_log(ll x , ll y , ll mod) //快速乘
    {
        x %= mod , y %= mod ;
        ll ans = 0;
        while(y)
        {
            if(y & 1) ans = (ans + x) % mod ; 
            y >>= 1 ;
            x = (x + x) % mod ;
        }
        return ans;
    }
    ll ksc_O1(ll x , ll y , ll mod) //快速乘
    {
        x %= mod , y %= mod ;
        ll z = (ld)x * y / mod ;
        ll ans = x * y - z * mod ;
        if(ans < 0)  ans += mod ;
        else if(ans >= mod)  ans -= mod ;
        return ans ;
    }
    int cnt = 0 ;
    bool vis[maxn] ;
    int prime[maxn] ;
    void get_prime(int up) //素数筛
    {
        memset(vis , 0 , sizeof(vis)) ;
        vis[1] = 1 ;
        for(int i = 2 ; i <= up ; i ++)
        {
            if(!vis[i]) 
            prime[++ cnt] = i ;
            for(int j = 1 ; j <= cnt && i * prime[j] <= up ; j ++)
            {
                vis[i * prime[j]] = 1 ;
                if(i % prime[j] == 0) break ;
            }
        }
    }
    //begin 判定大素数
    ll mul(ll a , ll b , ll mod)
    {
        ll ret = 0 ;
        while(b) 
        {
            if(b & 1)  ret = (ret + a) % mod ;
            a = (a + a) % mod ;
            b >>= 1 ;
        }
        return ret ;
    }
    ll pow(ll a , ll b , ll mod)
    {
        ll ret = 1 ;
        while(b) 
        {
            if(b & 1)  ret = mul(ret , a , mod) ;
            a = mul(a , a , mod) ;
            b >>= 1 ;
        }
        return ret ;
    }
    bool check(ll a , ll n)
    {
        ll x = n - 1 ;
        int t = 0 ;
        while((x & 1) == 0) 
        {
            x >>= 1 ;
            t ++ ;
        }
        x = pow(a , x , n) ;
        ll y ;
        rep(i , 1 , t)
        {
            y = mul(x , x , n) ;
            if(y == 1 && x != 1 && x != n - 1)  return 1 ;
            x = y ;
        }
        if(y != 1) return 1 ;
        return 0 ;
    }
    bool Miller_Rabin(ll n) 
    {
        if(n == 2)  return 1 ;
        if(n == 1 || !(n & 1))  return 0 ;
        const int arr[12] = {2,3,5,7,11,13,17,19,23,29,31,37} ;
        rep(i , 0 , 11) 
        {
            if(arr[i] >= n) break ;
            if(check(arr[i] , n)) return 0 ;
        }
        return 1 ;
    }
    //end 判定大素数
    ll get_inv(ll x) //逆元
    {
       return qpow(x , mod - 2) % mod ;
    }
    ll inv1[maxn] ;  //乘法逆元
    void init1(int up)
    {
       inv1[1] = 1 ;
       for(int i = 2 ; i <= up ; i ++)
         inv1[i] = (ll)(mod - mod / i) * inv1[int(mod % (ll)i)] % mod ;
    }
    ll fac[maxn] ;
    ll inv[maxn] ; //阶乘逆元
    void init(int up) 
    {
       fac[0] = fac[1] = inv[0] = inv[1] = 1 ;
       for(int i = 2 ; i <= up ; i ++)
       {
         fac[i] = fac[i - 1] * i % mod ;
         inv[i] = -inv[mod % i] * (mod / i) % mod ;
         while(inv[i] < 0) inv[i] += mod ;
       }
       for(int i = 2 ; i <= up ; i ++)  
         inv[i] = inv[i] * inv[i - 1] % mod ;
    }
    ll C(int n , int m)
    {
        return fac[n] * inv[m] % mod * inv[n - m] % mod ;
    }
    void init()
    {
        vector<int> v[3300 + 10] ;
        get_prime(30000) ;
        int num = 0 ;
        rep(i , 1 , cnt)
        {
            int x = prime[i] ;
            for(int j = x ; j <= 30000 ; j *= x)  v[i].pb(j) , num ++ ;
        }
        rep(i , 1 , 30000)  lg[i] = log(i) ;
        rep(i , 1 , cnt)  per(j , 30000 , 1)  for(auto x : v[i])  if(j >= x)  dp[j] = max(dp[j] , dp[j - x] + lg[x]) ;
        rep(i , 1 , 30000)  dp[i] = max(dp[i] , dp[i - 1]) ;
    }
} em ;
int main()
{
    ios ;
    cout << fixed << setprecision(15) ;
    em.init() ;
    int T ;
    cin >> T ;
    while(T --)
    {
        int n ;
        cin >> n ;
        cout << dp[n] << '\n' ;
    }
    return 0 ;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值