2012 Asia Tianjin Regional Contest

本文深入探讨了算法与数据结构的关键概念,包括排序算法、动态规划、哈希算法等,旨在提供对计算机科学基础的全面理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

hdu4431 Mahjong

日麻XD

枚举/模拟,之前用一个桶来装牌来搜索结果一直TLE,后来改了一种更直接的搜索方法就可以AC了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
//#pragma comment(linker, "/STACK:16777216")
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define N 34

int cnt[N] , save[N];
int ans[N] , s;

bool qdz()
{
  int i , sum = 0;
  for (i = 0 ; i < 34 ; ++ i)
    sum += cnt[i] == 2;
  return sum == 7;
}
bool gsws()
{
  int i , sum = 0 , sum2 = 0;
  for (i = 0 ; i < 34 ; ++ i)
    if (i >= 27 || i % 9 == 0 || i % 9 == 8)
      sum += cnt[i] == 1 , sum2 += cnt[i] == 2;
  return sum == 12 && sum2 == 1;
}
int p[N];
bool f[N];
bool dfs(int dep)
{
  if (dep == 4) return 1;
  int i , j , k;
  for (i = 0 ; f[i] ; ++ i);
  for (j = i + 1 ; j < 12 ; ++ j)
    if (!f[j] && p[j] == p[i]) break;
  for (k = j + 1 ; k < 12 ; ++ k)
    if (!f[k] && p[k] == p[i]) break;
  if (j < 12 && k < 12)
  {
  f[i] = f[j] = f[k] = 1;
  if (dfs(dep + 1)) return 1;
  f[i] = f[j] = f[k] = 0;}
  if (p[i] < 27 && p[i] % 9 < 7)
  {
  for (j = i + 1 ; j < 12 ; ++ j)
    if (!f[j] && p[j] == p[i] + 1) break;
  for (k = j + 1 ; k < 12 ; ++ k)
    if (!f[k] && p[k] == p[i] + 2) break;
  if (j < 12 && k < 12)
  {
  f[i] = f[j] = f[k] = 1;
  if (dfs(dep + 1)) return 1;
  f[i] = f[j] = f[k] = 0;}
  }
  return 0;
}

void work()
{
  int i , j , k , x; char ma[5];
  memset(cnt , 0 , sizeof(cnt));
  for (i = 0 ; i < 13 ; ++ i)
  {
    scanf("%s" , ma);
    if (ma[1] == 'm') j = 0;
    if (ma[1] == 's') j = 1;
    if (ma[1] == 'p') j = 2;
    if (ma[1] == 'c') j = 3;
    ++ cnt[j * 9 + *ma - '1'];
  }
  memcpy(save , cnt , sizeof(cnt));
  s = 0;
  for (i = 0 ; i < 34 ; ++ i)
  {
    if (cnt[i] < 4)
    {
      ++ cnt[i];
      if (qdz() || gsws())
      {
        ans[s ++] = i;
        -- cnt[i];
        continue;
      }
      for (j = 0 ; j < 34 ; ++ j)
        if (cnt[j] >= 2)
        {
          cnt[j] -= 2;
          x = 0; memset(f , 0 , sizeof(f));
          for (k = 0 ; k < 34 ; ++ k)
            for (int l = 0 ; l < cnt[k] ; ++ l)
              p[x ++] = k;
          if (dfs(0))  break;
          cnt[j] += 2;
        }
      if (j < 34) ans[s ++] = i;;
      memcpy(cnt , save , sizeof(cnt));
    }
  }
  if (!s)
    puts("Nooten");
  else
  {
    printf("%d " , s);
    for (i = 0 ; i < s ; ++ i)
      printf("%c%c%c" , ans[i] % 9 + '1' , "mspc"[ans[i] / 9] , " \n"[i == s - 1]);
  }
}
int main()
{
  int _; scanf("%d" , &_); while (_--)
  //while (~scanf("%d",&n))
    work();
  return 0;
}

hdu4432 Sum of divisors 

sqrt{n}枚举因子,直接统计。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
//#pragma comment(linker, "/STACK:16777216")
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;

int n , m ;
int cal(int x)
{
  int sum = 0 , i;
  while (x)
    i = x % m , sum += i * i , x /= m;
  return sum;
}
vector<int> digit;
void work()
{
  int i ; LL ans = 0; digit.clear();
  for (i = 1 ; i * i <= n ; ++ i)
    if (n % i == 0)
    {
      ans += cal(i);
      if (i * i != n)
        ans += cal(n / i);
    }
  while (ans)
    digit.push_back(ans % m) , ans /= m;
  for (i = digit.size() - 1 ; i >= 0 ; -- i)
    if (digit[i] < 10)
      printf("%d" , digit[i]);
    else putchar(digit[i] - 10 + 'A');
  puts("");
}

int main()
{
  while (~scanf("%d%d",&n,&m))
    work();
  return 0;
}
hdu4433 locker

f[i][j][k]表示前i位归位第i+1位为j第i+2位为k的最小步数。

可以给a和b末尾加两个0来避免可能的特判

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
//#pragma comment(linker, "/STACK:16777216")
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define N 1005
char a[N] , b[N];
int n , f[N][10][10];

void work()
{
  int i , j , k , l , x , y , z;
  n = strlen(a + 1);
  a[++ n] = '0' , b[n] = '0';
  a[++ n] = '0' , b[n] = '0';
  a[n + 1] = 0 , b[n + 1] = 0;
  for (i = 0 ; i <= n ; ++ i)
  {
    a[i] -= '0' , b[i] -= '0';
    for (j = 0 ; j < 10 ; ++ j)
      for (k = 0 ; k < 10 ; ++ k)
        f[i][j][k] = 1 << 30;
  }
  f[0][a[1]][a[2]] = 0;
  for (i = 1 ; i <= n - 2 ; ++ i)
  {
    for (j = 0 ; j < 10 ; ++ j)
      for (k = 0 ; k < 10 ; ++ k)
        if (f[i - 1][j][k] < 1 << 30)
        // i -> j , i + 1 -> k
        {
          z = (10 + b[i] - j) % 10;
          for (x = 0 ; x <= z ; ++ x)
            for (y = 0 ; y <= x ; ++ y)
              f[i][(k + x) % 10][(a[i + 2] + y) % 10] = min(f[i][(k + x) % 10][(a[i + 2] + y) % 10] , f[i - 1][j][k] + z);

          z = (10 + j - b[i]) % 10;
          for (x = 0 ; x <= z ; ++ x)
            for (y = 0 ; y <= x ; ++ y)
              f[i][(k - x + 10) % 10][(a[i + 2] - y + 10) % 10] = min(f[i][(k - x + 10) % 10][(a[i + 2] - y + 10) % 10] , f[i - 1][j][k] + z);
        }
  }
  cout << f[n - 2][0][0] << endl;
}

int main()
{
  while (~scanf("%s%s", a+1, b+1))
    work();
  return 0;
}
hdu4435 charge-station

贪心,从大到小看一个加油站的存在是否是必要的,判断答案的时候用BFS求出达到没有油站的点的最小耗油数。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
//#pragma comment(linker, "/STACK:16777216")
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define N 128
int n , X[N] , Y[N] , D , g[N][N];
bool build[N] , f[N];
int d[N];
bool check()
{
  int i , x , y;
  memset(f , 0 , sizeof(f));
  for (i = 0 ; i < n ; ++ i)
    if (build[i])
      d[i] = 0;
    else d[i] = 1 << 29;
  queue<int> Q; Q.push(0) , f[0] = 1;
  while (!Q.empty())
  {
    x = Q.front() , Q.pop();
    for (y = 0 ; y < n ; ++ y)
      if (!f[y] && g[x][y] <= D)
      {
        d[y] = min(d[y] , d[x] + g[x][y]);
        if (build[y])
          f[y] = 1 , Q.push(y);
      }
  }
  for (i = 0 ; i < n ; ++ i)
    if (build[i] && !f[i] || !build[i] && d[i] + d[i] > D)
      return 0;
  return 1;
}

void work()
{
  int i , j;
  for (i = 0 ; i < n ; ++ i)
    scanf("%d%d",&X[i],&Y[i]);
  for (i = 0 ; i < n ; ++ i)
    for (j = i + 1 ; j < n ; ++ j)
      g[i][j] = g[j][i] = ceil(sqrt((X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j])) - 1e-9);
  memset(build , 1 , sizeof(build));
  if (!check())
    puts("-1");
  else
  {
    for (i = n - 1 ; i >= 0 ; -- i)
    {
      build[i] = 0;
      if (!check())
        build[i] = 1;
    }
    for (i = n - 1 ; !build[i] ; -- i);
    for ( ; i >= 0 ; -- i) printf("%d" , build[i]);
    puts("");
  }
}

int main()
{
  while (~scanf("%d%d", &n, &D))
    work();
  return 0;
}

hdu4436 str2int
求出后缀数组之后,对每个串的后缀都线性递推出其所有前缀代表的数字之和,就有一个明显的递推关系。
累计答案的时候不需要考虑0开头的后缀,也不需要考虑之前有重复的LCP。
在纸上推推式子就能推出来,不是很难。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
//#pragma comment(linker, "/STACK:16777216")
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define N 110005
int n , m ; int s[N];
int sa[N] , t1[N] , t2[N] , c[N];
int rank[N] , height[N];

void buildsa(int m)
{
  int i , k , *x = t1 , *y = t2;
  for (i = 0 ; i < m ; ++ i) c[i] = 0;
  for (i = 0 ; i < n ; ++ i) ++ c[x[i] = s[i]];
  for (i = 1 ; i < m ; ++ i) c[i] += c[i - 1];
  for (i = n - 1 ; i >= 0 ; -- i) sa[-- c[x[i]]] = i;
  for (k = 1 ; k <= n ; k <<= 1)
  {
    int p = 0;
    for (i = n - k ; i < n ; ++ i) y[p ++] = i;
    for (i = 0 ; i < n ; ++ i) if (sa[i] >= k) y[p ++] = sa[i] - k;
    for (i = 0 ; i < m ; ++ i) c[i] = 0;
    for (i = 0 ; i < n ; ++ i) ++ c[x[y[i]]];
    for (i = 1 ; i < m ; ++ i) c[i] += c[i - 1];
    for (i = n - 1 ; i >= 0 ; -- i) sa[-- c[x[y[i]]]] = y[i];
    swap(x , y) , p = 1 , x[sa[0]] = 0;
    for (i = 1 ; i < n ; ++ i)
      x[sa[i]] = (y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k]) ? p - 1 : p ++;
    if (p >= n) break;
    m = p;
  }
  k = 0;
  for (i = 0 ; i < n ; ++ i) rank[sa[i]] = i;
  for (i = 0 ; i < n ; ++ i)
  {
    if (k) -- k; if (!rank[i]) continue;
    int j = sa[rank[i] - 1];
    while (s[i + k] == s[j + k]) ++ k;
    height[rank[i]] = k;
  }
}

char str[N];
int f[N] , power[N] , id[N] , num[N] , p10[N];
int Q = 2012;
void work()
{
  int i , j , k , x , y , len , sum = 0;
  n = 0;
  memset(f , 0 , sizeof(f));
  memset(id , 0 , sizeof(id));
  memset(num , 0 , sizeof(num));
  for (i = 1 ; i <= m ; ++ i)
  {
    scanf("%s" , str);
    len = strlen(str);
    for (j = len - 1 , k = 0 ; j >= 0 ; -- j , ++ k)
    {
      f[n + j] = f[n + j + 1] + power[k] * (str[j] - '0') , f[n + j] %= Q;
      id[n + j] = k;
    }
    for (k = 0 ; k < len ; ++ k)
      num[n + k + 1] = (k ? num[n + k] : 0) * 10 + str[k] - '0' , num[n + k + 1] %= Q;
    for (j = 0 ; str[j] ; ++ j)
      s[n ++] = m + 1 + str[j] - '0';
    s[n ++] = i;
  }
  buildsa(m + 15);
  int st = 0;
  while (st < n && s[sa[st]] <= m + 1) ++ st;

  for (i = st ; i < n ; ++ i)
  {
    j = height[i];
    sum += f[sa[i] + j] + (num[sa[i]+j] - num[sa[i]] * p10[j] % Q + Q) % Q * (power[id[sa[i]] - j + 1] + 2011) % Q;
    sum %= Q;
  }
  cout << sum << endl;
}

int main()
{
  power[0] = p10[0] = 1;
  for (int i = 1 ; i <= 110002 ; ++ i)
    power[i] = power[i - 1] * 10 + 1 , power[i] %= Q ,
    p10[i] = p10[i - 1] * 10 , p10[i] %= Q;
  while (~scanf("%d", &m))
    work();
  return 0;
}
hdu4438 Hunters
直接可以计算出两个期望,比较输出。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
//#pragma comment(linker, "/STACK:16777216")
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define N 1005
char a[N] , b[N];
int n , f[N][10][10];

void work()
{
  double x , y , p , q , a , b;
  scanf("%lf%lf%lf%lf",&x,&y,&p,&q);
  a = q * p * (x + y) + (1 - q) * x;
  b = q * y + (1 - q) * p * (x + y);
  if (a > b)
    printf("tiger %.4f\n" , a);
  else printf("wolf %.4f\n" , b);
}

int main()
{
  //freopen("~input.txt" , "r" , stdin);
  //freopen("output.txt" , "w" , stdout);
  int _; scanf("%d" , &_); while (_--)
  //while (~scanf("%s%s", a+1, b+1))
    work();
  return 0;
}
hdu4441 Queue Sequence
用splay维护整个数列,用set维护每次insert的数字
insert的p的位置的时候如果1~p之间有k个正数,负数就肯定在第k+1个负数的前一个位置。
剩下两个操作就很简单了。
发现splay用的还是不熟,找第k+1个负数的代码写了很久。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
//#pragma comment(linker, "/STACK:16777216")
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define N 200005

struct splay_tree
{
  int root , nodecnt , c[N][2] , size[N] , par[N] , type[N] , stack[N];
  int key[N] , sp[N] , sm[N];
  LL sum[N];
  int rub[N] , rs;
  void clear()
  {
    root = 0 , size[0] = 0 , type[0] = -1;
    c[0][0] = c[0][1] = par[0] = 0;
    nodecnt = 0 , rs = 0;
  }
  int malloc(int k)
  {
    int x;
    if (rs) x = rub[rs --]; else x = ++ nodecnt;
    sum[x] = key[x] = k , size[x] = 1 , type[x] = -1;
    c[x][0] = c[x][1] = par[x] = 0;
    sp[x] = (k > 0) , sm[x] = (k < 0);
    return x;
  }
  void pushdown(int x)
  {
  }
  void pushup(int x)
  {
    if (!x) return; pushdown(x);  pushdown(c[x][0]);  pushdown(c[x][1]);
    sum[x] = key[x] , size[x] = 1 , sp[x] = (key[x] > 0) , sm[x] = (key[x] < 0);
    if(c[x][0]) sum[x] += sum[c[x][0]] , sp[x] += sp[c[x][0]] , sm[x] += sm[c[x][0]] , size[x] += size[c[x][0]];
    if(c[x][1]) sum[x] += sum[c[x][1]] , sp[x] += sp[c[x][1]] , sm[x] += sm[c[x][1]] , size[x] += size[c[x][1]];
  }
  void rotate (int x)
  {
    int t = type[x] , y = par[x] , z = c[x][t ^ 1];
    type[x] = type[y] , par[x] = par[y];
    if (~type[x]) c[par[x]][type[x]] = x;
    type[y] = t ^ 1 , par[y] = x , c[x][t ^ 1] = y;
    if (x) type[z] = t , par[z] = y;
    c[y][t] = z , pushup(y);
  }
  void splay(int x)
  {
    int cnt = 0 , i; stack[++ cnt] = x;
    for (i = x ; ~type[i] ; i = par[i])
      stack[++ cnt] = par[i];
    for (i = cnt ; i > 0 ; -- i) pushdown(stack[i]);
    while (~type[x])
    {
      int y = par[x];
      if (type[x] == type[y])rotate(y) ;else rotate(x);
      if (!~type[x]) break;
      rotate(x);
    }
    pushup(x);
  }
  int Rank(int x)
  {
    splay(x) , root = x; return size[c[x][0]] + 1;
  }
  int getKth(int x , int k)
  {
    while (1)
    {
      pushdown(x);
      if (size[c[x][0]] + 1 == k) break;
      if (size[c[x][0]] + 1 > k)
        x = c[x][0];
      else
        k -= size[c[x][0]] + 1 , x = c[x][1];
    }
    return x;
  }
  int getKthMin(int x , int k)
  {
    while (1)
    {
      pushdown(x);
      if (sm[c[x][0]] + (key[x] < 0) >= k)
      {
        if (sm[c[x][0]] < k) break;
        x = c[x][0];
      }
      else
        k -= sm[c[x][0]] + (key[x] < 0) , x = c[x][1];
    }
    return x;
  }
  void split(int p , int& x , int& y , int a)
  {
    if (a == size[p]) {x = p , y = 0;return;}
    y = getKth(p , a + 1) , splay(y);
    x = c[y][0] , type[x] = -1 , c[y][0] = 0 , par[x] = 0;
    pushup(y);
  }
  void merge(int& p , int x ,int y)
  {
    if (!x || !y) {p = x | y ; return;} pushdown(x);
    p = getKth(x , size[x]) , splay(p) , c[p][1] = y;
    type[y] = 1 , par[y] = p , pushup(p);
  }
  void print(int x)
  {
    pushdown(x);
    if (c[x][0]) print(c[x][0]);
    printf("%d ", key[x]);
    if (c[x][1]) print(c[x][1]);
  }
};
set<int> node;
int cnt , id[N][2];
splay_tree T;
int ca , m;

void work()
{
  int i , j , x , y , z , p , q , num; char str[10];
  T.clear();
  cnt = 0 , node.clear();

  printf("Case #%d:\n" , ++ ca);
  while (m --)
  {
    scanf("%s" , str);
    if (*str == 'i')
    {
      scanf("%d",&p);
      if (node.size())
        i = *node.begin() , node.erase(i);
      else i = ++ cnt;

      T.split(T.root , x , y , p);
      num = T.sp[x];
      id[i][0] = z = T.malloc(i);
      T.merge(x , x , z);
      T.merge(T.root , x , y);
      if (T.sm[T.root] == num)
      {
        id[i][1] = z = T.malloc(-i);
        T.merge(T.root , T.root , z);
      }
      else
      {
        p = T.Rank(T.getKthMin(T.root , num + 1));
        T.split(T.root , x , y , p - 1);
        id[i][1] = z = T.malloc(-i);
        T.merge(x , x , z);
        T.merge(T.root , x , y);
      }
    }
    if (*str == 'r')
    {
      scanf("%d",&i);
      p = T.Rank(id[i][0]);
      T.split(T.root , x , y , p - 1);
      T.split(y , y , z , 1);
      T.merge(T.root , x , z);
      T.rub[++ T.rs] = y;
      p = T.Rank(id[i][1]);
      T.split(T.root , x , y , p - 1);
      T.split(y , y , z , 1);
      T.merge(T.root , x , z);
      T.rub[++ T.rs] = y;
      node.insert(i);
    }
    if (*str == 'q')
    {
      scanf("%d",&i);
      p = T.Rank(id[i][0]);
      q = T.Rank(id[i][1]);
      T.split(T.root , x , y , p - 1);
      T.split(y , y , z , q - p + 1);
      printf("%I64d\n" , T.sum[y]);
      T.merge(y , y , z);
      T.merge(T.root , x , y);
    }
   // T.print(T.root);puts("");
  }

}


int main()
{
  while (~scanf("%d",&m))
    work();
  return 0;
}









### 参与ICPC亚洲日本赛区线上第一轮比赛的信息和规则 #### 比赛概述 国际大学生程序设计竞赛(International Collegiate Programming Contest, ICPC)是一项全球性的编程竞赛活动。其中,ICPC亚洲区域赛分为多个赛区,包括中国、韩国以及日本等地的比赛。对于希望参加ICPC Asia Japan Online First-Round Contest的学生来说,了解具体的参赛信息至关重要。 #### 报名条件 通常情况下,只有在校本科生或者研究生可以组队报名参加此类赛事[^1]。每支队伍由三名队员组成,并且需要指定一名指导教师负责监督整个过程。需要注意的是,不同年份的具体规定可能会有所变化,因此建议关注官方发布的最新通知来获取最准确的要求。 #### 注册流程 为了能够顺利参与到比赛中去,团队应该尽早完成在线注册手续。这一般涉及到填写基本信息表格并提交给主办方审核通过之后才能正式成为参赛者之一。此外,在线平台还会提供练习环境供选手熟悉系统操作方式及其功能特性[^2]。 #### 赛事形式 该类竞赛多采用限时解题的形式来进行考核,即给出若干道算法题目让各小组在规定时间内解答尽可能多的问题以获得更高分数。期间允许查阅资料但严禁作弊行为的发生。值得注意的是,由于这是线上初选阶段,所以不存在现场答辩环节[^3]。 #### 准备工作 准备过程中除了要掌握扎实的数据结构与算法基础知识外,还应当注重培养良好的协作沟通能力以便于更好地发挥集体智慧解决问题。另外也可以参考往届真题集锦加深理解常见考点分布情况从而提高实战水平[^4]。 ```cpp // 示例代码用于展示如何处理输入输出流加速读取效率 #include<bits/stdc++.h> using namespace std; void solve(){ // 解决具体问题逻辑实现部分... } signed main(){ ios::sync_with_stdio(false); int T; cin >> T; while(T--)solve(); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值