• 模板(持续更新中。。)


    LCA

    Tarjan代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define RG register
    inline int read()
    {
        int sum = 0;
        char c = getchar();
        while(c<'0' || c>'9')
            c = getchar();
        while(c>='0' && c<='9')
            sum = sum*10+c-'0', c = getchar();
        return sum;
    }
    const int N = 500010;
    struct node
    {
        int to, next;
    }g[N*2];
    struct nod
    {
        int to, next, num;
    }a[N*2];
    int fa[N], last[N], gl, bj[N], n, m, s, ans[N], al, la[N];
    int find(int x)
    {
        if(fa[x] == x)
            return x;
        return fa[x] = find(fa[x]);
    }
    void add(int x, int y)
    {
        g[++gl].to = y;
        g[gl].next = last[x];
        last[x] = gl;
    }
    void add2(int x, int y, int i)
    {
        a[++al].to = y;
        a[al].next = la[x];
        a[al].num = i;
        la[x] = al;
    }
    void tarjan(int x, int lat)
    {
        fa[x] = x;
        bj[x] = 1;
        for(int i = last[x]; i; i = g[i].next)
        {
            int to = g[i].to;
            if(to == lat) continue;
            tarjan(to, x);
            fa[to] = x;
        }
        for(int i = la[x]; i; i=a[i].next)
            if(bj[a[i].to])
                ans[a[i].num] = find(a[i].to);
        return ;
    }
    void write(int x)
    {
        if(x)
        {
            write(x/10);
            putchar((x%10+'0'));
        }
        return ;
    }
    int main()
    {
        n = read(), m = read(), s = read();
        for(RG int i = 1; i < n; i++)
        {
            int x=read(),y=read();
            add(x,y);add(y,x);
        }
        for(RG int i = 1; i <= m; i++)
        {
            int x=read(),y=read();
            add2(x, y, i), add2(y, x, i);
        }
        tarjan(s, 0);
        for(RG int i = 1; i <= m; i++)
            write(ans[i]), putchar('
    ');
        return 0;
    }
    
    

    倍增代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define RG register
    inline int read()
    {
        int sum = 0;
        char c = getchar();
        while(c<'0' || c>'9')
            c = getchar();
        while(c>='0' && c<='9')
            sum = sum*10+c-'0', c = getchar();
        return sum;
    }
    void write(int x)
    {
        if(x)
        {
            write(x/10);
            putchar((x%10+'0'));
        }
        return ;
    }
    const int N = 500010;
    struct node
    {
        int to, next;
    }g[N*2];
    int last[N], gl;
    void add(int x, int y)
    {
        g[++gl] = (node){y, last[x]};
        last[x] = gl;
    }
    int anc[N][21], fa[N], deep[N];
    void work(int x)
    {
        anc[x][0] = fa[x];
        for(int i=1; (1<<i) <= deep[x]; i++)
            anc[x][i] = anc[anc[x][i-1]][i-1];
        for(int i = last[x]; i; i = g[i].next)
            if(fa[x] != g[i].to)
            {
                fa[g[i].to] = x;
                deep[g[i].to] = deep[x]+1;
                work(g[i].to);
            }
        return ;
    }
    int lca(int x, int y)
    {
        if(deep[x] < deep[y])
            swap(x, y); //x比y深
        for(int i = 20; i >= 0; i--)
            if(deep[y] <= deep[x]-(1<<i))//注意是<=(想想为什么?)
                x = anc[x][i];
        if(x == y)
            return x;
        for(int i = 20; i >= 0; i--)
        {
            if(anc[x][i]!=anc[y][i])
            {
                x=anc[x][i];
                y=anc[y][i];
            }
        }
        return anc[x][0];//最后一次肯定跳一个点
    }
    int main()
    {
        int n = read(), m = read(), s = read();
        for(RG int i = 1; i < n; i++)
        {
            int x=read(),y=read();
            add(x,y);add(y,x);
        }
        work(s);
        for(RG int i = 1; i <= m; i++)
        {
            int x=read(), y=read();
            write(lca(x,y));
            putchar('
    ');
        }
        return 0;
    }
    
    

    【模板】单源最短路径Dijkstra+堆优化

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 100010;
    const int M = 200010;
    struct Edge
    {
        int to, next, w;
    }g[M];
    int last[N], gl;
    void add(int x, int y, int z)
    {
        g[++gl] = (Edge){y, last[x], z};
        last[x] = gl;
    }
    int dis[N];
    struct node
    {
        int dist, num;
        bool operator < (node z)
        const
        {
            return dist > z.dist;
        }
    };
    priority_queue<node> q;
    bool bj[N];
    int main()
    {
        int n, m, s;
        scanf("%d%d%d", &n, &m, &s);
        for(int i = 1; i <= m; i++)
        {
            int x, y, z;
            scanf("%d%d%d", &x, &y, &z);
            add(x, y, z);
        }
        memset(dis, 127, sizeof(dis));
        dis[s] = 0;
        q.push((node){0, s});
        while(!q.empty())
        {
            while(!q.empty() && bj[q.top().num])
                q.pop();
            if(q.empty()) break;
            int u = q.top().num;
            bj[u] = 1;
            q.pop();
            for(int i = last[u]; i; i = g[i].next)
            {
                int v = g[i].to;
                if(dis[v] > dis[u]+g[i].w)
                {
                    dis[v] = dis[u]+g[i].w;
                    q.push((node){dis[v], v});
                }
            }
        }
        for(int i = 1; i <= n; i++)
            printf("%d ", dis[i]);
        printf("
    ");
        return 0;
    }
    

    【模板】树链剖分

    
    #include<bits/stdc++.h>
    #define LL long long
    const int N = 1e5+10;
    using namespace std;
    
    inline void Swap(int &x, int &y){int z = x^y; y ^= z; x ^= z;return ;}
    inline int gi(){int sum = 0, f = 1;char c = getchar();while(c!='-' && (c < '0' || c > '9'))c = getchar();if(c == '-') f = -1, c = getchar();while(c>='0' && c<='9') sum = sum*10+c-'0', c = getchar();return sum*f;}
    
    int n, m, r, p, w[N];
    struct tree
    {
        int to, next;
    }g[N*2];
    int last[N], gl;
    inline void add(int x, int y){g[++gl] = (tree){y, last[x]};last[x] = gl;return;}
    int dep[N], siz[N], top[N], id[N], cnt, son[N], fa[N], t[N];
    
    void dfs1(int x, int f, int depth)
    {
        dep[x] = depth;
        fa[x] = f;
        siz[x] = 1;
        int MAX = 0;
        for(int i = last[x]; i; i = g[i].next)
        {
            int to = g[i].to;
            if(to != f)
            {
                dfs1(to, x, depth+1);
                siz[x] += siz[to];
                if(siz[to] > MAX) MAX = siz[to], son[x] = to;
            }
        }
        return ;
    }
    void dfs2(int x, int topf)
    {
        id[x] = ++cnt;
        top[x] = topf;
        t[cnt] = w[x];
        if(!son[x]) return ;
        dfs2(son[x], topf);
        for(int i = last[x]; i; i = g[i].next)
        {
            int to = g[i].to;
            if(to != fa[x] && to != son[x])
                dfs2(to, to);
        }
        return ;
    }
    
    struct node
    {
        int v, lazy;
    }st[N*4];
    
    inline void pushdown(int l, int r, int rt)
    {
        if(st[rt].lazy)
        {
            int lazy = st[rt].lazy, mid = (l+r) >> 1, ls = rt<<1, rs = rt<<1|1;
            st[rt].lazy = 0;
            st[ls].lazy += lazy;
            st[ls].lazy %= p;
    
            st[ls].v += lazy*(mid-l+1);
            st[ls].v %= p;
    
            st[rs].lazy += lazy;
            st[ls].lazy %= p;
    
            st[rs].v += lazy*(r-mid);
            st[rs].v %= p;
        }
        return ;
    }
    void build(int l, int r, int rt)
    {
        if(l == r)
        {
            st[rt].v = t[l]%p;
            return ;
        }
        int mid = (l+r) >> 1;
        build(l, mid, rt<<1);
        build(mid+1, r, rt<<1|1);
        st[rt].v = (st[rt<<1].v + st[rt<<1|1].v)%p;
        return ;
    }
    void update(int l, int r, int L, int R, int rt, int k)
    {
        if(L <= l && r <= R)
        {
            st[rt].lazy += k;
            st[rt].lazy %= p;
            st[rt].v += k*(r-l+1);
            st[rt].v %= p;
            return ;
        }
        int mid = (l+r) >> 1;
        pushdown(l, r, rt);
        if(L <= mid)
            update(l, mid, L, R, rt<<1, k);
        if(R > mid)
            update(mid+1, r, L, R, rt<<1|1, k);
        st[rt].v = (st[rt<<1].v + st[rt<<1|1].v)%p;
        return ;
    }
    int query(int l, int r, int L, int R, int rt)
    {
        if(L <= l && r <= R)
            return st[rt].v;
        int ans = 0, mid = (l+r) >> 1;
        pushdown(l, r, rt);
        if(L <= mid)
            ans = query(l, mid, L, R, rt<<1);
        if(R > mid)
            ans += query(mid+1, r, L, R, rt<<1|1);
        return ans%p;
    }
    
    inline void upway(int x, int y, int z)
    {
        z %= p;
        while(top[x] != top[y])
        {
            if(dep[top[x]] < dep[top[y]]) Swap(x, y);
            update(1, n, id[top[x]], id[x], 1, z);
            x = fa[top[x]];
        }
        if(dep[x] > dep[y]) Swap(x, y);
        update(1, n, id[x], id[y], 1, z);
        return ;
    }
    
    inline int qway(int x, int y)
    {
        int ans = 0;
        while(top[x] != top[y])
        {
            if(dep[top[x]] < dep[top[y]]) Swap(x, y);
            ans += query(1, n, id[top[x]], id[x], 1);
            ans %= p;
            x = fa[top[x]];
        }
        if(dep[x] > dep[y]) Swap(x, y);
        ans += query(1, n, id[x], id[y], 1);
        return ans%p;
    }
    
    inline void upsub(int x, int k)
    {
        update(1, n, id[x], id[x]+siz[x]-1, 1, k);
        return ;
    }
    inline int qsub(int x)
    {
        return query(1, n, id[x], id[x]+siz[x]-1, 1);
    }
    
    int main()
    {
        n = gi(); m = gi(); r = gi(); p = gi();
        for(int i = 1; i <= n; i++) w[i] = gi()%p;
        for(int i = 1; i < n; i++)
        {
            int x = gi(), y = gi();
            add(x, y); add(y, x);
        }
        dfs1(r, 0, 1);
        dfs2(r, r);
        build(1, n, 1);
        for(int i = 1; i <= m; i++)
        {
            int k = gi();
            if(k == 1)
            {
                int x = gi(), y = gi(), z = gi();
                upway(x, y, z);
            }
            else
            if(k == 2)
            {
                int x = gi(), y = gi();
                printf("%d
    ", qway(x, y));
            }
            else
            if(k == 3)
            {
                int x = gi(), y = gi();
                upsub(x, y);
            }
            else
            {
                int x = gi();
                printf("%d
    ", qsub(x));
            }
        }
        return 0;
    }
    

    Splay模板

    文艺平衡树

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    using namespace std;
    const int N = 100010;
    struct Splay {
        int v, ch[2], f, s;
        bool o;
    }t[N];
    void up(int x) {
        t[x].s = t[t[x].ch[0]].s + t[t[x].ch[1]].s + 1;
    }
    inline void rotate(int x) {
        int y = t[x].f, z = t[y].f, k = (t[y].ch[1] == x);
        t[z].ch[(t[z].ch[1]==y)] = x; t[x].f = z;
        t[y].ch[k] = t[x].ch[k^1]; t[t[x].ch[k^1]].f = y;
        t[x].ch[k^1] = y; t[y].f = x;	
        up(y);
        return ;
    }
    int rt;
    
    inline void pushdown(int x) {
        if (t[x].o) {
            swap(t[x].ch[0], t[x].ch[1]);
            t[x].o = 0;
            t[t[x].ch[0]].o ^= 1;
            t[t[x].ch[1]].o ^= 1;
        }
        return ;
    }
    
    inline int K(int z) {
        int x = rt;
        while (1) {
            pushdown(x);
            int l = t[x].ch[0];
            if (t[l].s+1 < z) {
                x = t[x].ch[1];
                z -= (t[l].s+1);
            }
            else {
                if (t[l].s >= z)
                    x = l;
                else return x;
            }	
        }
    }
    
    inline void splay(int x, int goal) {
        while (t[x].f != goal) {
            int y = t[x].f, z = t[y].f;
            if (z != goal)
                (t[z].ch[1] == y) == (t[y].ch[1] == x) ? rotate(y) : rotate(x);
            rotate(x);
        }
        up(x);
        if (!goal) rt = x;	
        return ;
    }
    int cnt;
    void insert(int k) {
        int x = rt, f = 0;
        while (x)
            f = x, x = t[x].ch[(t[x].v < k)];
        t[++cnt].f = f; t[cnt].v = k;
        t[f].ch[t[f].v < k] = cnt;
        splay(cnt, 0);
        return ;
    }
    void reverse(int L, int R) {
        int l = K(L), r = K(R+2);
        splay(l, 0); splay(r, l);
        t[t[t[rt].ch[1]].ch[0]].o ^= 1;
        return ;
    }
    int n;
    void write(int x) {
        pushdown(x);
        if (t[x].ch[0]) write(t[x].ch[0]);
        if (t[x].v > 1 && t[x].v < n+2) printf("%d ", t[x].v-1);
        if (t[x].ch[1]) write(t[x].ch[1]);
        return ;
    }
    
    int main() {
        int m;
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n+2; i++) insert(i);
        for (int i = 1; i <= m; i++) {
            int l, r;
            scanf("%d%d", &l, &r);
            reverse(l, r);
        }
        write(rt);
        return 0;
    }
    

    平衡树

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    
    #define N 500010
    const int INF = 2147483647;
    
    using namespace std;
    
    inline int gi() {
        register int x=0,t=1;
        char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-'){t=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
        return x*t;
    }
    
    int r, tot;
    
    struct node {
        int ch[2], f, cnt, v, s;
    }t[N];
    inline void up(int x) {
        t[x].s = t[t[x].ch[0]].s + t[t[x].ch[1]].s + t[x].cnt;
        return ;
    }
    inline void rotate(int x) {
        int y = t[x].f; int z = t[y].f, k = (t[y].ch[1] == x);
        t[z].ch[t[z].ch[1] == y] = x; t[x].f = z;
        t[y].ch[k] = t[x].ch[k^1]; t[t[x].ch[k^1]].f = y;
        t[x].ch[k^1] = y; t[y].f = x;
        up(y);
        return ;
    }
    
    void splay(int x, int goal) {
        while (t[x].f != goal) {
            int y = t[x].f; int z = t[y].f;
            if (z != goal)
                if ((t[y].ch[1] == x) == (t[z].ch[1] == y)) rotate(x); else rotate(y);
            rotate(x);
        }
        up(x);
        if (!goal) r = x;
        return ;
    }
    
    void insert(int x) {
        int rt = r, f = 0;
        while (rt && t[rt].v != x) {
            f = rt;
            rt = t[rt].ch[t[rt].v<x]; 
        }
        if (rt)
            t[rt].cnt++;
        else {
            rt = ++tot;
            if (f)
                t[f].ch[t[f].v<x] = rt;
            t[rt].v = x;
            t[rt].f = f;
            t[rt].s = t[rt].cnt = 1;
        }
        splay(rt, 0);
        return ;
    }
    
    void find(int x) {
        int rt = r;
        while (t[rt].v != x && t[rt].ch[t[rt].v<x]) rt = t[rt].ch[t[rt].v<x];
        splay(rt, 0);
        return ;
    }
    
    int Next(int x, int bj) {
        find(x);
        int rt = r;
        if ((bj && t[rt].v > x) || (!bj && t[rt].v < x)) return rt;
        rt = t[rt].ch[bj];
        bj ^= 1;
        while (t[rt].ch[bj]) rt = t[rt].ch[bj];
        return rt;
    }
    
    void del(int x) {
        int a = Next(x, 0), b = Next(x, 1);
        splay(a, 0); splay(b, a);
        int c = t[b].ch[0];
        if (t[c].cnt > 1) {
            t[c].cnt--;
            splay(c, 0);
        }
        else t[b].ch[0] = 0;
        return ;
    }
    
    int K(int x) {
        int rt = r;
        while (1) {
            int l = t[rt].ch[0];
            if (t[l].s + t[rt].cnt < x) {
                x -= (t[rt].cnt + t[l].s);
                rt = t[rt].ch[1];
            }
            else 
                if (t[l].s >= x)
                    rt = l;
                else return t[rt].v;
        }
    }
    
    int main() {
        insert(INF); insert(-INF);
        int T = gi();
        while (T--) {
            int k = gi();
            if (k == 1) insert(gi());
            else if (k == 2) del(gi());
            else if (k == 3) {
                find(gi());
                printf("%d
    ", t[t[r].ch[0]].s);
            }
            else if (k == 4)
                printf("%d
    ", K(gi()+1));
            else if (k == 5) printf("%d
    ", t[Next(gi(), 0)].v);
            else printf("%d
    ", t[Next(gi(), 1)].v);
        }
        return 0;
    }
    

    KMP模板

    #include<bits/stdc++.h>
    using namespace std;
    inline int gi() {
        char ch=getchar(); int x=0,q=0;
        while(ch<'0'||ch>'9') q=ch=='-'?1:q,ch=getchar();
        while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        return q?-x:x;
    }
    const int N = 1000010;
    char s1[N], s2[N];
    int l1, l2, nxt[N];
    
    void kmp() {
        int j = 0;
        for (int i = 1; i <= l1; i++) {
            while (j && s1[i-1] != s2[j]) j = nxt[j];
            if (s1[i-1] == s2[j]) j++;
            if (j == l2)
                printf("%d
    ", i-l2+1), j = nxt[j];
        }
        return ;
    }
    
    int main() {
        cin>>s1>>s2;
        l1 = strlen(s1); l2 = strlen(s2);
        nxt[1] = 0;
        for (int i = 2; i <= l2; i++) {
            int j = nxt[i-1];
            while (j && s2[i-1] != s2[j])
                j = nxt[j];
            if (s2[i-1] == s2[j]) j++;
            nxt[i] = j;
        }
        kmp();
        for (int i = 1; i <= l2; i++)
            printf("%d ", nxt[i]);
        printf("
    ");
        return 0;
    }
    

    二分图匹配(匈牙利算法)模板

    #include<bits/stdc++.h>
    
    using namespace std;
    
    inline int gi() {
        int f = 1, s = 0;
        char c = getchar();
        while (c != '-' && (c < '0' || c > '9')) c = getchar();
        if (c == '-') f = -1, c = getchar();
        while (c >= '0' && c <= '9') s = s*10+c-'0', c = getchar();
        return f == 1 ? s : -s;
    }
    
    const int N = 1000010;
    
    struct node {
        int to, next;
    }g[N];
    
    int match[1010], gl, last[1010], used[1010];
    
    inline int pp(int x) {
        for (int i = last[x]; i; i = g[i].next) {
            int v = g[i].to;
            if (used[v]) continue;
            used[v] = 1;
            if (!match[v] || pp(match[v])) {
                match[v] = x;
                return 1;
            }
        }
        return 0;
    }
    
    void add(int x, int y) {
        g[++gl] = (node) {y, last[x]};
        last[x] = gl;
    }
    
    int main() {
        int n = gi(), m = gi(), e = gi();
        for (int i = 1; i <= e; i++) {
            int x = gi(), y = gi();
            if (x <= n && y <= m) add(x, y);
        }
        int ans = 0;
        for (int i = 1; i <= n; i++) {
            memset(used, 0, sizeof(used));
            ans += pp(i);
        }
        printf("%d
    ", ans);
        return 0;
    }
    

    求区间第K大(主席树模板)

    #include<bits/stdc++.h>
    
    using namespace std;
    
    inline int gi() {
        int f = 1, s = 0;
        char c = getchar();
        while (c != '-' && (c < '0' || c > '9')) c = getchar();
        if (c == '-') f = -1, c = getchar();
        while (c >= '0' && c <= '9') s = s*10+c-'0', c = getchar();
        return f == 1 ? s : -s;
    }
    
    const int N = 200010;
    
    struct node {
        int v, id;
        bool operator < (node z) const {
            return v < z.v;
        }
    }a[N];
    
    int b[N], cnt;
    
    struct tree {
        int lc, rc, v;
    }t[N*20];
    int root[N], ans[N];
    
    void update(int l, int r, int pos, int &now) {
        t[++cnt] = t[now];
        now = cnt;
        t[now].v++;
        if (l == r) return ;
        int mid = (l + r) >> 1;
        if (pos <= mid)
            update(l, mid, pos, t[now].lc);
        else update(mid+1, r, pos, t[now].rc);
        return ;
    }
    
    int query(int l, int r, int rt1, int rt2, int k) {
        if (l == r) return l;
        int s = t[t[rt2].lc].v - t[t[rt1].lc].v, mid = (l + r) >> 1;
        if (s >= k)
            return query(l, mid, t[rt1].lc, t[rt2].lc, k);
        else return query(mid+1, r, t[rt1].rc, t[rt2].rc, k - s);
    }
    
    int main() {
        int n = gi(), m = gi();
        for (int i = 1; i <= n; i++) {
            a[i].v = gi(); a[i].id = i;
        }
        sort(a+1, a+1+n);
        int v = 1;
        b[a[1].id] = v; ans[v] = a[1].v;
        for (int i = 2; i <= n; i++) {
            if (a[i].v != a[i-1].v) v++;
            b[a[i].id] = v; ans[v] = a[i].v;
        }
        for (int i = 1; i <= n; i++) {
            root[i] = root[i-1];
            update(1, n, b[i], root[i]);
        }
        while (m--) {
            int l = gi(), r = gi(), k = gi();
            printf("%d
    ", ans[query(1, n, root[l-1], root[r], k)]);
        }
        return 0;
    }
    
    
    

    【模板】三维偏序(陌上花开)

    //cdq套cdq
    
    #include<bits/stdc++.h>
    using namespace std;
    const int N = 100010;
    
    struct node {
        int a, b, c, id;
        bool flag;
        bool operator < (node z) const {
            return a < z.a || (a == z.a && b < z.b) || (a == z.a && b == z.b && c < z.c);
        }
    }s[N], b[N], c[N];
    
    int ans[N], d[N];
    
    void merge2(int l, int r) {
        if (l == r) return;
        int mid = (l + r) >> 1, cnt = 0;//cnt记前面和当前点满足条件的个数
        merge2(l, mid); merge2(mid+1, r);
        for (int i = l, j = mid+1, k = l; k <= r; k++) {
            if ((j > r || b[j].c >= b[i].c) && i <= mid) {
                c[k] =  b[i++];
                cnt += c[k].flag;//是前半部分的点就+1
            }
            else {
                c[k] = b[j++];
                if (!c[k].flag) ans[c[k].id] += cnt;//在后半部分表明当前点的b大于前半部分的任意一个点的b
            }
        }
        for (int i = l; i <= r; i++)
            b[i] = c[i];
        return ;
    }
    
    void merge(int l, int r) {
        if (l == r) return ;
        int mid = (l + r) >> 1;
        merge(l, mid); merge(mid+1, r);
        for (int i = l, j = mid+1, k = l; k <= r; k++) {
            if ((j > r || s[j].b >= s[i].b) && i <= mid) {
                b[k] = s[i++];
                b[k].flag = 1;//当前点为前半部分
            }
            else {
                b[k] = s[j++];
                b[k].flag = 0;
            }
        }
        for (int i = l; i <= r; i++) s[i] = b[i];
        merge2(l, r);
        return ;
    }
    
    int main() {
        int n, k;
        scanf("%d%d", &n, &k);
        for (int i = 1; i <= n; i++) {
            scanf("%d%d%d", &s[i].a, &s[i].b, &s[i].c);
            s[i].id = i;
        }
        sort(s+1, s+1+n);
        for (int i = n-1; i >= 1; i--) 
            if (s[i].a == s[i+1].a && s[i].b == s[i+1].b && s[i].c == s[i+1].c) ans[s[i].id] = ans[s[i+1].id]+1;//对于完全相等的,i > j 的点对在cdq分治中已经求了,所以只用求 i < j 的点对个数
        merge(1, n);
        for (int i = 1; i <= n; i++) d[ans[i]]++;
        for (int i = 0; i < n; i++) printf("%d
    ", d[i]);
        return 0;
    }
    
    //cdq+树状数组
    #include<bits/stdc++.h>
    using namespace std;
    const int N = 100010;
    struct node {
        int a, b, c, cnt, id;
        bool operator <(const node &z) const {
            return a < z.a || (a == z.a && b < z.b) || (a == z.a && b == z.b && c < z.c);
        }
    }s[N], tmp[N];
    int t[200010], n, k;
    #define lowbit(x) (x&(-x))
    void add(int x, int z) {
        while (x <= k) {
            t[x] += z;
            x += lowbit(x);
        }
        return ;
    }
    int sum(int x) {
        int sm = 0;
        while (x) {
            sm += t[x];
            x -= lowbit(x);
        }
        return sm;
    }
    int ans[N], cnt[N];
    void cdq(int l, int r) {
        if (l == r) return ;
        int mid = (l + r) >> 1;
        cdq(l, mid); cdq(mid+1, r);
        for (int i = l, j = mid+1, k = l; k <= r; k++) {
            if (i <= mid && (j > r || s[i].b <= s[j].b)) {
                add(s[i].c, s[i].cnt);
                tmp[k] = s[i++];
            }
            else {
                ans[s[j].id] += sum(s[j].c);
                tmp[k] = s[j++];
            }
        }
        for (int i = l; i <= mid; i++) add(s[i].c, -s[i].cnt);
        for (int i = l; i <= r; i++) s[i] = tmp[i];
        return ;
    }
    int main() {
        scanf("%d%d", &n, &k);
        for (int i = 1; i <= n; i++) scanf("%d%d%d", &s[i].a, &s[i].b, &s[i].c), s[i].id = i;
        sort(s+1, s+1+n);
        int z = 1, num = 0;
        for (int i = 1; i <= n; i++) {
            int z = i;
            while (s[z].a == s[z+1].a && s[z].b == s[z+1].b && s[z].c == s[z+1].c)
                z++;
            s[i].cnt = z-i+1;
            s[++num] = s[i];
            i = z;
        }
        cdq(1, num);
        for (int i = 1; i <= num; i++) cnt[ans[s[i].id]+s[i].cnt-1]+=s[i].cnt;
        for (int i = 0; i < n; i++) printf("%d
    ", cnt[i]);
        return 0;
    }
    
    #include<bits/stdc++.h>
    
    #define LL long long
    #define RG register
    const int N = 300010;
    using namespace std;
    
    inline int gi() {
    	RG int x = 0; RG char c = getchar(); bool f = 0;
    	while (c != '-' && (c < '0' || c > '9')) c = getchar();
    	if (c == '-') c = getchar(), f = 1;
    	while (c >= '0' && c <= '9') x = x*10+c-'0', c = getchar();
    	return f ? -x : x;
    }
    
    struct node {
    	int v, s, fa, ch[2];
    	bool rev;
    }t[N];
    int S[N], top;
    void putrev(int x) {
    	swap(t[x].ch[0], t[x].ch[1]);
    	t[x].rev ^= 1;
    	return ;
    }
    #define pushup(x) (t[x].s = (t[x].v^t[t[x].ch[0]].s^t[t[x].ch[1]].s))
    void pushdown(int x) {
    	if (t[x].rev) {
    		if (t[x].ch[0]) putrev(t[x].ch[0]);
    		if (t[x].ch[1]) putrev(t[x].ch[1]);
    		t[x].rev = 0;
    	}
    	return ;
    }
    #define get(x) (t[t[x].fa].ch[1]==x)
    bool isroot(int x) {
    	return (t[t[x].fa].ch[0] != x) && (t[t[x].fa].ch[1] != x);
    }
    void rotate(int x) {
    	int k = get(x), y = t[x].fa, z = t[y].fa;
    	if (!isroot(y)) t[z].ch[get(y)] = x;
    	t[x].fa = z;
    	t[t[x].ch[k^1]].fa = y, t[y].ch[k] = t[x].ch[k^1];
    	t[y].fa = x, t[x].ch[k^1] = y;
    	pushup(y);
    	return ;
    }
    void splay(int x) {
    	S[top = 1] = x;
    	for (RG int i = x; !isroot(i); i = t[i].fa) S[++top] = t[i].fa;
    	for (RG int i = top; i; i--) pushdown(S[i]);
    	while (!isroot(x)) {
    		int y = t[x].fa;
    		if (!isroot(y))
    			(get(x) ^ get(y)) ? rotate(x) : rotate(y);
    		rotate(x);
    	}
    	pushup(x);
    	return ;
    }
    void access(int x) {
    	for (int y = 0; x; y = x, x = t[x].fa)
    		splay(x), t[x].ch[1] = y, pushup(x);
    	return ;
    }
    void makeroot(int x) {
    	access(x); splay(x);putrev(x);
    	return ;
    }
    inline int findroot(int x) {
    	access(x); splay(x);
    	while (t[x].ch[0]) pushdown(x), x = t[x].ch[0];
    	return x;
    }
    void link(int x, int y) {
    	makeroot(x);
    	if (findroot(y) == x) return ;
    	t[x].fa = y;
    	return ;
    }
    void split(int x, int y) {
    	makeroot(x), access(y), splay(y);
    	return ;
    }
    void cut(int x, int y) {
    	makeroot(x);
    	if (findroot(y) == x && t[x].fa == y && !t[x].ch[1])
    		t[x].fa = t[y].ch[0] = 0, pushup(y);
    	return ;
    }
    
    
    int main() {
    	int n = gi(), T = gi();
    	for (RG int i = 1; i <= n; i++) t[i].v = gi();
    	while (T--) {
    		int op = gi(), x = gi(), y = gi();
    		if (!op) {
    			split(x, y);
    			printf("%d
    ", t[y].s);
    		}
    		else if (op == 1) link(x, y);
    		else if (op == 2) cut(x, y);
    		else {
    			access(x); splay(x); t[x].v = y; pushup(x);
    		}
    	}
    	return 0;
    }
    

    左偏树模板

    #include<bits/stdc++.h>
    
    #define LL long long
    #define RG register
    
    using namespace std;
    
    inline int gi() {
        RG int x = 0; RG char c = getchar(); bool f = 0;
        while (c != '-' && (c < '0' || c > '9')) c = getchar();
        if (c == '-') c = getchar(), f = 1;
        while (c >= '0' && c <= '9') x = x*10+c-'0', c = getchar();
        return f ? -x : x;
    }
    const int N = 100010;
    int fa[N], ch[N][2], a[N], dis[N];
    inline int merge(int x, int y) {
        if (!x || !y) return x+y;
        if (a[x] > a[y] || (a[x] == a[y] && x > y))
            swap(x, y);
        ch[x][1] = merge(ch[x][1], y);
        fa[ch[x][1]] = x;
        if (dis[ch[x][1]] > dis[ch[x][0]]) swap(ch[x][1], ch[x][0]);
        dis[x] = dis[ch[x][1]]+1;
        return x;
    }
    
    inline int get(int x) {
        while (fa[x]) x = fa[x];
        return x;
    }
    bool flag[N];
    inline void del(int x) {
        x = get(x);
        printf("%d
    ", a[x]);
        flag[x] = 1;
        fa[ch[x][0]] = fa[ch[x][1]] = 0;
        merge(ch[x][0], ch[x][1]);
    }
    
    int main() {
        //freopen(".in", "r", stdin);
        //freopen(".out", "w", stdout);
        int n = gi(), m = gi();
        dis[0] = -1;
        for (int i = 1; i <= n; i++) a[i] = gi();
        while (m--) {
            int opt = gi();
            if (opt == 1) {
                int x = gi(), y = gi();
                if (flag[x] || flag[y]) continue;
                x = get(x); y = get(y);
                if (x == y) continue;
                merge(x, y);
            }
            else {
                int x = gi();
                if (flag[x]) printf("-1
    ");
                else del(x);
            }
        }
        return 0;
    }
    

    【模板】杜教筛(Sum)

    (g(1)S(n)=sum_{i=1}^{n}(f*g)(i)-sum_{i=2}^{n}g(i)S(lfloor frac{n}{i} floor))

    其中(g = f*1)

    #include<bits/stdc++.h>
    
    #define LL long long
    #define RG register
    
    using namespace std;
    
    inline int gi() {
    	RG int x = 0; RG char c = getchar(); bool f = 0;
    	while (c != '-' && (c < '0' || c > '9')) c = getchar();
    	if (c == '-') c = getchar(), f = 1;
    	while (c >= '0' && c <= '9') x = x*10+c-'0', c = getchar();
    	return f ? -x : x;
    }
    const int N = 6000000;
    int p[N], tot;
    LL phi[N+1], mu[N+1];
    bool zs[N+1];
    
    void init() {
    	mu[1] = 1; phi[1] = 1;
    	for (int i = 2; i <= N; i++) {
    		if (!zs[i]) {
    			p[++tot] = i;
    			mu[i] = -1;
    			phi[i] = i-1;
    		}
    		for (int j = 1; j <= tot && p[j]*i <= N; j++) {
    			zs[p[j]*i] = 1;
    			if (!(i%p[j])) {
    				phi[i*p[j]] = phi[i]*p[j];
    				break;
    			}
    			mu[i*p[j]] = -mu[i];
    			phi[i*p[j]] = phi[i]*(p[j]-1);
    		}
    	}
    	for (int i = 2; i <= N; i++)
    		mu[i] += mu[i-1], phi[i] += phi[i-1];
    	return ;
    }
    map<LL, LL> M1, M2;
    LL getphi(int x) {
    	if (x <= N) return phi[x];
    	if (M1[x]) return M1[x];
    	LL S = (x+1)*1ll*x/2;
    	for (int l = 2, r; l <= x; l = r+1) {
    		r = (x/(x/l));
    		S -= getphi(x/l)*(r-l+1);
    	}
    	return M1[x] = S; 
    }
    
    LL getmu(int x) {
    	if (x <= N) return mu[x];
    	if (M2[x]) return M2[x];
    	LL S = 1;
    	for (int l = 2, r; l <= x; l = r+1) {
    		r = (x/(x/l));
    		S -= getmu(x/l)*(r-l+1);
    	}
    	return M2[x] = S;
    }
    
    int main() {
    	//freopen(".in", "r", stdin);
    	//freopen(".out", "w", stdout);
    	int t = gi();
    	init();
    	while (t--) {
    		int n = gi();
    		printf("%lld %lld
    ", getphi(n), getmu(n));
    	}
    	return 0;
    }
    
    

    【模板】扩展中国剩余定理(EXCRT)

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 10;
    #define int __int128
    #define RG register
    template<class T> inline void read(T &x) {
        x = 0; RG char c = getchar(); bool f = 0;
        while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
        while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
        x = f ? -x : x;
        return ;
    }
    template<class T> inline void write(T x) {
        if (!x) {putchar(48);return ;}
        if (x < 0) x = -x, putchar('-');
        int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
        for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
    }
    int n, A1, B1, A2, B2, k1, k2, d;
    void exgcd(int a, int b, int &x, int &y, int &d) {
    	if (!b) return (void) (x = 1, y = 0, d = a);
    	exgcd(b, a % b, y, x, d); y -= a / b * x;
    }
     main() {
    	freopen("in.txt", "r", stdin);
    	read(n), read(B1), read(A1);
    	for (int i = 2; i <= n; i++) {
    		read(B2); read(A2);
    		exgcd(B1, B2, k1, k2, d);
    		B1 *= B2 / d; k2 = -k2;
    		k2 *= (A2 - A1) / d;
                    k2 = (k2 % B1 + B1) % B1;
    		A1 = (k2 % B1 * B2 % B1 + A2) % B1;
    	}
    	write(A1);
    	return 0;
    }
    
    

    【模板】扩展卢卡斯

    #include<bits/stdc++.h>
    
    #define LL long long
    #define RG register
    LL ksm(LL x, LL y, LL M) {
        LL s = 1;
        while (y) {
            if (y&1) s = s*x%M;
            x = x*x%M;
            y >>= 1;
        }
        return s;
    }
    using namespace std;
    template<class T> inline void read(T &x) {
        x = 0; RG char c = getchar(); bool f = 0;
        while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
        while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
        x = f ? -x : x;
        return ;
    }
    template<class T> inline void write(T x) {
        if (!x) {putchar(48);return ;}
        if (x < 0) x = -x, putchar('-');
        int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
        for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
    }
    
    void exgcd(LL a, LL b, LL &x, LL &y) {
        if (!b) {x = 1, y = 0; return ;}
        exgcd(b, a%b, y, x);
        y -= a/b*x;
        return ;
    }
    
    LL inv(LL a, LL M) {
        if (!a) return 0;
        LL x, y; exgcd(a, M, x, y);
        if (x < 0) x += M;
        x %= M;
        return x;
    }
    
    LL calc(LL n, LL pi, LL pk) {
        if (!n) return 1;
        LL ans = 1;
        for (LL i = 2; i <= pk; i++)
            if (i%pi) ans = ans*i%pk;
        ans = ksm(ans, n/pk, pk);
        for (LL i = 2; i <= n%pk; i++)
            if (i%pi) ans = ans*i%pk;
        return ans*calc(n/pi, pi, pk)%pk;
    }
    
    LL C(LL n, LL m, LL Mod, LL pi, LL pk) {
        if (m > n) return 0;
        LL a = calc(n, pi, pk), b = calc(m, pi, pk), c = calc(n-m, pi, pk), k = 0;
        for (LL i = n; i; i /= pi) k += i/pi;
        for (LL i = m; i; i /= pi) k -= i/pi;
        for (LL i = n-m; i; i /= pi) k-= i/pi;
        return a*inv(b, pk)%pk*inv(c, pk)%pk*ksm(pi, k, pk)%pk;
    }
    LL lucas(LL n, LL m, LL Mod) {
        LL ans = 0, x = Mod;
        for (LL i = 2; i <= x; i++)
            if (!(x%i)) {
                LL pk = 1;
                while (!(x%i)) pk *= i, x /= i;
                ans = (ans+C(n, m, Mod, i, pk)*(Mod/pk)%Mod*inv(Mod/pk, pk)) % Mod;
            }
    	return ans;
    }
    int main() {
        //freopen(".in", "r", stdin);
        //freopen(".out", "w", stdout);
    	LL n, m, Mod;
        read(n); read(m); read(Mod);
        write(lucas(n, m, Mod));
        return 0;
    }
    
    

    【模板】网络最大流(Dinic+当前弧优化)

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    
    #define LL long long
    #define RG register
    
    using namespace std;
    template<class T> inline void read(T &x) {
        x = 0; RG char c = getchar(); bool f = 0;
        while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
        while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
        x = f ? -x : x;
        return ;
    }
    template<class T> inline void write(T x) {
        if (!x) {putchar(48);return ;}
        if (x < 0) x = -x, putchar('-');
        int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
        for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
    }
    const int M = 200010, N = 10010, inf = 2147483647;
    int n, m, s, t;
    
    struct node {
        int to, nxt, w;
    }g[M];
    int last[N], gl = 1, cur[N];
    void add(int x, int y, int z) {
        g[++gl] = (node) {y, last[x], z};
        last[x] = gl;
    }
    
    queue<int> q;
    
    int dep[N];
    
    bool bfs() {
        q.push(s);
        memset(dep, 0, sizeof(dep));
        dep[s] = 1;
        while (!q.empty()) {
            int u = q.front(); q.pop();
            for (int i = last[u]; i; i = g[i].nxt) {
                int v = g[i].to;
                if (g[i].w && !dep[v])
                    dep[v] = dep[u]+1, q.push(v);
            }
        }
        return dep[t] ? 1 : 0;
    }
    
    int dfs(int u, int d) {
        if (u == t) return d;
        for (int &i = cur[u]; i; i = g[i].nxt) {
            int v = g[i].to;
            if (dep[v] == dep[u]+1 && g[i].w) {
                int di = dfs(v, min(d, g[i].w));
                if (di) {
                    g[i].w -= di;
                    g[i^1].w += di;
                    return di;
                }
            }
        }
        return 0;
    }
    
    int main() {
        read(n); read(m); read(s); read(t);
        for (int i = 1; i <= m; i++) {
            int u, v, w; read(u); read(v); read(w);
            add(u, v, w); add(v, u, 0);
        }
        int ans = 0;
        while (bfs()) {
            for (int i = 1; i <= n; i++)
                cur[i] = last[i];
            while (int d = dfs(s, inf))
                ans += d;
        }
        printf("%d
    ", ans);
        return 0;
    }
    

    【模板】最小费用最大流

    #include<bits/stdc++.h>
    
    #define LL long long
    #define RG register
    
    using namespace std;
    template<class T> inline void read(T &x) {
        x = 0; RG char c = getchar(); bool f = 0;
        while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
        while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
        x = f ? -x : x;
        return ;
    }
    template<class T> inline void write(T x) {
        if (!x) {putchar(48);return ;}
        if (x < 0) x = -x, putchar('-');
        int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
        for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
    }
    
    const int N = 5010, M = 100010, inf = 2147483647;
    
    int n, m, s, t;
    
    struct node {
        int to, nxt, w, v;
    }g[M];
    int last[N], gl = 1;
    void add(int x, int y, int w, int v) {
        g[++gl] = (node) {y, last[x], w, v};
        last[x] = gl;
    }
    int pre[N], from[N], dis[N];
    bool vis[N];
    
    queue<int> q;
    
    bool spfa() {
        for (int i = 1; i <= n; i++) dis[i] = inf;
        memset(vis, 0, sizeof(vis));
        q.push(s);
        dis[s] = 0;	
        while (!q.empty()) {
            int u = q.front(); q.pop();
            vis[u] = 0;
            for (int i = last[u]; i; i = g[i].nxt) {
                int v = g[i].to;
                if (g[i].w && dis[v] > dis[u]+g[i].v) {
                    dis[v] = dis[u]+g[i].v;
                    from[v] = i; pre[v] = u;
                    if (!vis[v]) {
                        vis[v] = 1;
                        q.push(v);
                    }
                }
            }
        }
        return !(dis[t] == inf);
    }
    
    int main() {
        read(n); read(m); read(s); read(t);
        for (int i = 1; i <= m; i++) {
            int u, v, w, va; read(u), read(v), read(w), read(va);
            add(u, v, w, va), add(v, u, 0, -va);
        }
        int flow = 0, cost = 0;
        while (spfa()) {
            int di = inf;
            for (int i = t; i != s; i = pre[i])
                di = min(di, g[from[i]].w);
            flow += di; cost += di*dis[t];
            for (int i = t; i != s; i = pre[i])
                g[from[i]].w -= di, g[from[i]^1].w += di;
        }
        printf("%d %d
    ", flow, cost);
        return 0;
    }
    
    

    AC自动机

    #include<bits/stdc++.h>
    
    #define LL long long
    #define RG register
    
    using namespace std;
    template<class T> inline void read(T &x) {
        x = 0; RG char c = getchar(); bool f = 0;
        while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
        while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
        x = f ? -x : x;
        return ;
    }
    template<class T> inline void write(T x) {
        if (!x) {putchar(48);return ;}
        if (x < 0) x = -x, putchar('-');
        int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
        for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
    }
    
    struct Tree {
        int fail, end;
        int s[26];
    }t[1000000];
    int cnt = 0;
    
    char s[1000010];
    
    void insert() {
        int len = strlen(s), now = 0;
        for (int i = 0; i < len; i++) {
            if (!t[now].s[s[i]-'a'])
                t[now].s[s[i]-'a'] = ++cnt;
            now = t[now].s[s[i]-'a'];
        }
        t[now].end++;
        return ;
    }
    
    queue<int> q;	
    void get_fail() {
        for (int i = 0; i < 26; i++)
            if (t[0].s[i]) {
                t[t[0].s[i]].fail = 0;
                q.push(t[0].s[i]);
            }
        while (!q.empty()) {
            int x = q.front(); q.pop();
            for (int i = 0; i < 26; i++)
                if (t[x].s[i]) {
                    t[t[x].s[i]].fail = t[t[x].fail].s[i];
                    q.push(t[x].s[i]);
                }
                else t[x].s[i] = t[t[x].fail].s[i];
        }
    }
    
    int query() {
        int len = strlen(s), now = 0, ans = 0;
        for (int i = 0; i < len; i++) {
            now = t[now].s[s[i]-'a'];
            for (int j = now; j && t[j].end != -1; j = t[j].fail) {
                ans += t[j].end;
                t[j].end = -1;
            }
        }
        return ans;
    }
    
    int main() {
        int n;
        read(n);
        for (int i = 1; i <= n; i++) {
            scanf("%s", s);
            insert();
        }
        get_fail();
        scanf("%s", s);
        write(query());
        return 0;
    }
    
    

    Miller_Rabin(检测素数)

    #include<bits/stdc++.h>
    
    #define LL long long
    #define RG register
    
    using namespace std;
    template<class T> inline void read(T &x) {
    	x = 0; RG char c = getchar(); bool f = 0;
    	while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
    	while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
    	x = f ? -x : x;
    	return ;
    }
    template<class T> inline void write(T x) {
    	if (!x) {putchar(48);return ;}
    	if (x < 0) x = -x, putchar('-');
    	int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
    	for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
    }
    
    LL P[]= {2,3,5,7,11,13,17,19};
    
    LL fpow(LL a, LL b, LL Mod) {
    	LL res = 1;
    	for (; b; b >>= 1, a = a * a % Mod) if (b & 1) res = res * a % Mod;
    	return res;
    }
    bool MillerRabin(LL a, LL p) {
    	LL t = p - 1;
    	int k = 0;
    	while (t % 2 == 0) t >>= 1, k++;
    	LL now = fpow(a, t, p), lst = now;
    	for (int i = 1; i <= k; i++) {
    		now = now * now % p;
    		if (now == 1) {
    			if (lst != p - 1 && lst != 1) return 0;
    			return 1;
    		}
    		lst = now;
    	}
    	return 0;
    }
    bool prime(LL p) {
    	for (int i = 0; i < 8; i++) if (P[i] == p) return 1;
    	if (p < 2 || ((p & 1) == 0)) return 0;
    	for (int i = 0; i < 8; i++) if (!MillerRabin(P[i], p)) return 0;
    	return 1;
    }
    
    int main() {
    	int n, m;
    	read(n), read(m);
    	while (m--) {
    		LL x;
    		read(x);
    		puts(prime(x) ? "Yes" : "No");
    	}
    	return 0;
    }
    
    

    Pollard-Rho算法

    #include<bits/stdc++.h>
    
    #define LL long long
    #define RG register
    
    using namespace std;
    template<class T> inline void read(T &x) {
    	x = 0; RG char c = getchar(); bool f = 0;
    	while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
    	while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
    	x = f ? -x : x;
    	return ;
    }
    template<class T> inline void write(T x) {
    	if (!x) {putchar(48);return ;}
    	if (x < 0) x = -x, putchar('-');
    	int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
    	for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
    }
    inline LL mul(LL x, LL y, LL mod) {
    	return (__int128) x * y % mod;
    }
    int P[] = {2, 3, 5, 7, 11, 13, 17, 19};
    LL fpow(LL a, LL b, LL c) {
    	LL res = 1;
    	for (; b; b >>= 1, a = mul(a, a, c)) if (b & 1) res = mul(res, a, c);
    	return res;
    }
    bool MillerRabin(LL a, LL p) {
    	LL x = p - 1;
    	int k = 0;
    	while (x % 2 == 0) x >>= 1, k++;
    	LL now = fpow(a, x, p), lst = now;
    	for (int i = 1; i <= k; i++) {
    		now = mul(now, now, p);
    		if (now == 1) {
    			if (lst == 1 || lst == p - 1) return 1;
    			return 0;
    		}
    		lst = now;
    	}
    	return 0;
    }
    bool prime(LL n) {
    	for (int i = 0; i < 8; i++) if (n == P[i]) return 1;
    	if (n < 2 || !(n & 1)) return 0;
    	for (int i = 0; i < 8; i++) if (!MillerRabin(P[i], n)) return 0;
    	return 1;
    }
    LL ans;
    LL gcd(LL x, LL y) {
    	return !y ? x : gcd(y, x % y);
    }
    LL f(LL x, LL c, LL n) {
    	return (mul(x, x, n) + c) % n;
    }
    LL make(LL n) {
    	LL lst = 0, now = 0, c = 1ll * rand() % (n - 1) + 1;
    	for (int k = 1; ; k <<= 1) {
    		LL S = 1;
    		for (int i = 1; i <= k; i++) {
    			now = f(now, c, n);
    			S = mul(S, abs(now - lst), n);
    			if (S % 127 == 0) {
    				LL d = gcd(S, n);
    				if (d > 1) return d;
    			}
    		}
    		LL d = gcd(S, n);
    		if (d > 1) return d;
    		lst = now;
    	}
    }
    void PollardRho(LL x) {
    	if (x <= ans) return ;
    	if (prime(x)) {
    		ans = max(ans, x);
    		return ;
    	}
    	LL p = x;
    	while (p == x) p = make(x);
    	while (x % p == 0) x /= p;
    	PollardRho(x); PollardRho(p);
    }
    
    int main() {
    	int T;
    	read(T);
    	srand(time(NULL));
    	while(T--) {
    		LL n; ans = 1;
    		read(n);
    		PollardRho(n);
    		if (ans == n) puts("Prime");
    		else printf("%lld
    ", ans);
    	}
    	return 0;
    }
    
    

    BSGS

    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<map>
    using namespace std;
    #define LL long long
    map<int, int> M;
    int BSGS(int a, int b, int p) {
    	if (b == 1 && a) return 0;
    	M.clear(); int m = ceil(sqrt(p));
    	LL t = 1;
    	for (int i = 0; i < m; i++, t = t * a % p) M[t * b % p] = i;
    	for (int i = 1, s = t; i <= m + 1; i++, s = t * s % p) {
    		map<int, int> :: iterator it = M.find(s);
    		if (it == M.end()) continue;
    		return m * i - (it->second);
    	}
    	return -1;
    }
    int main() {
    	int a, b, p;
    	while (scanf("%d%d%d", &p, &a, &b) != EOF) {
    		int ans = BSGS(a, b, p);
    		if (ans == -1) puts("no solution");
    		else printf("%d
    ", ans);	
    	}
    	return 0;
    }
    

    EXBSGS

    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    const int Mod = 1e5 + 7;
    int gcd(int x, int y) {
    	return !y ? x : gcd(y, x % y);
    }
    struct Hash {
    	struct node {
    		int a, b, nxt;
    	} A[1000010];
    	int lst[Mod], tot;
    	void clear() { memset(lst, 0, sizeof(lst)); tot = 0; }
    	void add(int a, int b, int S) {
    		A[++tot] = (node) {a, b, lst[S]};
    		lst[S] = tot;
    	}
    	void insert(int a, int b) { add(a, b, a % Mod); }
    	int find(int x) {
    		for (int i = lst[x % Mod]; i; i = A[i].nxt)
    			if (A[i].a == x) return A[i].b;
    		return -1;
    	}
    } M;
    int exBSGS(int a, int b, int p) {
    	if (b == 1 && a) return 0;
    	int d, k = 0, s = 1;
    	while ((d = gcd(a, p)) > 1) {
    		if (b % d) { return -1; }
    		b /= d; p /= d; k++; s = 1ll * s * a / d % p;
    		if (s == b) { return k; }
    	}
    	M.clear(); int m = ceil(sqrt(p));
    	LL t = 1;
    	for (int i = 0; i < m; i++, t = t * a % p) M.insert(t * b % p, i);
    	s = t * s % p;
    	for (int i = 1; i <= m + 1; i++, s = t * s % p) {
    		int it = M.find(s); if (it == -1) continue;
            return m * i - it + k;
    	}
    	return -1;
    }
    int main() {
    	int a, b, p;
    	while (scanf("%d%d%d", &a, &p, &b) != EOF) {
    		if (!a && !b && !p) return 0;
    		int ans = exBSGS(a, b, p);
    		if (ans == -1) puts("No Solution");
    		else printf("%d
    ", ans);
    	}
    	return 0;	
    }
    
  • 相关阅读:
    python学习笔记(2)--sublimeText3运行python
    python学习笔记(1)--遍历txt文件,正则匹配替换文字
    JS学习笔记(4)--js变量的生命周期
    JS学习笔记(3)--json格式数据的添加,删除及排序方法
    JS学习笔记(2)--正则表达式获取指定字符串
    JS学习笔记(1)--sort排序
    VBA学习笔记(1)----VBA对象属性方法
    能够作图的软件都有哪些
    怎么用ChemDraw连接两个结构片段
    在几何画板上画椭圆可以根据椭圆第二定义
  • 原文地址:https://www.cnblogs.com/zzy2005/p/10197155.html
Copyright © 2020-2023  润新知