小技巧

//离散化数组
 for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            b[i] = a[i];
        }
        sort(a + 1, a + 1 + n);
        int cnt = unique(a + 1, a + 1 + n) - a - 1;
        for (int i = 1; i <= n; i++)
            b[i] = lower_bound(a + 1, a + 1 + cnt, b[i]) - a;
        for (int i = 1; i <= n; i++)
            cout << b[i] << endl;
//二维坐标点的离散
struct node {
    int x, y, sx, sy;
    //sx sy 为离散后坐标
}s[maxn];
bool cmpx(const node& a, const node& b) {
    return a.x < b.x;
}
bool cmpy(const node& a, const node& b) {
    return a.y < b.y;
}
int n, m, k,  arrx[maxn], arry[maxn];
int main()
{

    scanf("%d %d %d", &n, &m, &k);  //n,m为矩阵大小,k为有k个点,对其进行离散
    for (int i = 0; i < k; ++i) {
        scanf("%d %d", &s[i].x, &s[i].y);
        arrx[i] = s[i].x;
        arry[i] = s[i].y;
    }
    sort(s, s + k, cmpx);
    sort(arrx, arrx + k);
    n = unique(arrx, arrx + k) - arrx;
    int idx = 0;
    for (int i = 0; i < k; ++i) {
        if (s[i].x != arrx[idx])
            ++idx;
        s[i].sx = idx + 1;
    }
    sort(s, s + k, cmpy);
    sort(arry, arry + k);
    m = unique(arry, arry + k) - arry;
    idx = 0;
    for (int i = 0; i < k; ++i) {
        if (s[i].y != arry[idx])
            ++idx;
        s[i].sy = idx + 1;
    }
    for (int i = 0; i < k; ++i)
        cout << s[i].sx << " " << s[i].sy << endl;
}
//将一个数转换为A - Z的进制,比如3 -> C  34 -> AH  123 -> DS
void K(int n)
{
    if(n>26)
        K((n-1)/26);

    printf("%c",(n-1)%26+'A');
}
struct node{
    double x,y;
};
node a,b,c;
//求两个点之间的长度
double len(node a,node b) {
    double tmp = sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
    return tmp;
}
//给出三个点,求三角形的面积  海伦公式: p=(a+b+c)/2,S=sqrt(p(p-a)(p-b)(p-c))
double Area(node a,node b,node c){
    double lena = len(a,b);
    double lenb = len(b,c);
    double lenc = len(a,c);

    double p = (lena + lenb + lenc) / 2.0;
    double S = sqrt(p * (p - lena) * (p - lenb) * (p - lenc));
    return S;
}
//三角形求每条边对应的圆心角
void Ran() {
    double lena = len(a,b);
    double lenb = len(b,c);
    double lenc = len(a,c);
    double A = acos((lenb * lenb + lenc * lenc - lena * lena) / (2 * lenb * lenc));
    double B = acos((lena * lena + lenc * lenc - lenb * lenb) / (2 * lena * lenc));
    double C = acos((lena * lena + lenb * lenb - lenc * lenc) / (2 * lena * lenb));
}
//求外接圆半径r = a * b * c / 4S 
double R(node a,node b,node c) {
    double lena = len(a,b);
    double lenb = len(b,c);
    double lenc = len(a,c);
    double S = Area(a,b,c);
    double R = lena * lenb * lenc / (4.0 * S);
}
//dfs序,多组输入时记得init
int L[MAXN],R[MAXN];
int dep[MAXN];
int head[MAXN];
int cnt,tot;
struct node
{
    int u,v,w,next;
}s[MAXN << 1];
void Add(int u,int v) {
    s[tot].u = u;
    s[tot].v = v;
    s[tot].next = head[u];
    head[u] = tot++;
}
void dfs_xu(int u,int fa,int d)//dfs序
{
    L[u] = ++cnt;//开始时间戳
    dep[u] = d;//深度
    for (int i = head[u]; ~i; i = s[i].next) {
        int v = s[i].v;
        if (v == fa)
            continue;
        dfs_xu(v, u, d + 1);
    }
    R[u] = cnt;//结束时间戳
}
void init() {
    memset(s, 0, sizeof s);
    memset(L, 0, sizeof L);
    memset(R, 0, sizeof R);
    memset(head, -1, sizeof head);
    cnt = 0;
    tot = 0;
}
int main() {
    int n;
    cin >> n;
    init();
    for (int i = 1; i < n; i++) {
        int u, v;
        scanf("%d %d", &u, &v);
        Add(u, v);
        Add(v, u);
    }
    dfs_xu(1, -1, 1);
    for (int i = 1; i <= n; i++)
        printf("%d %d %d
", i, L[i], R[i]);
}
//优先队列按照s小的优先级
struct node{
    int s,pos;
    node(){}
    node(int xx,int pp): s(xx),pos(pp){}
    bool operator < (node a)const {
        return s > a.s;         //s小的优先级高
    }
};
priority_queue<node>que;
//逆元
void ex_gcd(LL a, LL b, LL &x, LL &y, LL &d){
    if (!b) {d = a, x = 1, y = 0;}
    else{
        ex_gcd(b, a % b, y, x, d);
        y -= x * (a / b);
    }
}
LL inv(LL t, LL p){//如果不存在,返回-1 
    LL d, x, y;
    ex_gcd(t, p, x, y, d);
    return d == 1 ? (x % p + p) % p : -1;
}
int main(){
    LL a, p;
    while(~scanf("%lld%lld", &a, &p)){
        printf("%lld
", inv(a, p));
    }
}
//组合数
const int N = 200000 + 5;
const int MOD = (int)1e9 + 7;
int F[N], Finv[N], inv[N];//F是阶乘,Finv是逆元的阶乘 
void init(){
    inv[1] = 1;
    for(int i = 2; i < N; i ++){
        inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;
    }
    F[0] = Finv[0] = 1;
    for(int i = 1; i < N; i ++){
        F[i] = F[i-1] * 1ll * i % MOD;
        Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD;
    }
}
int comb(int n, int m){//comb(n, m)就是C(n, m) 
    if(m < 0 || m > n) return 0;
    return F[n] * 1ll * Finv[n - m] % MOD * Finv[m] % MOD;
}
int main(){
    init();
}
//大组合数求模,p在10 ^ 5左右
typedef long long ll;
const int N =1e5;
ll n, m, p, fac[N];
void init()
{
    int i;
    fac[0] =1;
    for(i =1; i <= p; i++)
        fac[i] = fac[i-1]*i % p;
}
ll q_pow(ll a, ll b)
{
    ll  ans =1;
    while(b)
    {
        if(b &1)  ans = ans * a % p;
        b>>=1;
        a = a*a % p;
    }
    return  ans;
}

ll C(ll n, ll m)
{
    if(m > n)  return 0;
    return  fac[n]*q_pow(fac[m]*fac[n-m], p-2) % p;
}

ll Lucas(ll n, ll m )
{
    if(m ==0)  return 1;
    else return  (C(n%p, m%p)*Lucas(n/p, m/p))%p;
}

int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%lld%lld%lld", &n, &m, &p);
        init();
        printf("%lld
", Lucas(n, m));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/smallhester/p/11346254.html