zoukankan      html  css  js  c++  java
  • 吉林省赛及东北四省赛 模板

    线段树

    区间和,单点修改

    #include <bits/stdc++.h>
    typedef long long LL;
    const int maxn = 500000;
    
    using namespace std;
    
    struct tTree
    {
        LL sum;
        int l, r;
    };
    tTree tree[maxn*4+10];
    
    void pushup(int x)
    {
        if(tree[x].l == tree[x].r)
            return;
        tree[x].sum = tree[x*2].sum +tree[x*2+1].sum;
    }
    
    void build(int x, int l, int r)
    {
        tree[x].l = l; tree[x].r = r;
        if(tree[x].l == tree[x].r)
            scanf("%lld", &tree[x].sum);
        else
        {
            int mid = (l+r)/2;
            build(x*2, l, mid);
            build(x*2+1, mid+1, r);
            pushup(x);
        }
    }
    
    void modify(int x, int pos, int val)
    {
        if(tree[x].l == tree[x].r)
            tree[x].sum += val;
        else
        {
            int mid = (tree[x].l+tree[x].r)/2;
            if(pos <= mid)
                modify(x*2, pos, val);
            else
                modify(x*2+1, pos, val);
            pushup(x);
        }
    }
    
    LL query(int x, int l, int r)
    {
        if(tree[x].l>=l && tree[x].r<=r)
            return tree[x].sum;
        else
        {
            int mid = (tree[x].l+tree[x].r)/2;
            LL ret = 0;
            if(mid >= l)
                ret += query(x*2, l, r);
            if(mid+1 <= r)
                ret += query(x*2+1, l, r);
            return ret;
        }
    }
    
    int main()
    {
        int N, M;
        scanf("%d%d", &N, &M);
        build(1, 1, N);
        for(int i=1,op,x,y; i<=M; i++)
        {
            scanf("%d%d%d", &op, &x, &y);
            if(op == 1)
            {
                modify(1, x, y);
            }
            if(op == 2)
            {
                printf("%lld
    ", query(1, x, y));
            }
        }
        return 0;
    }
    

    区间和,区间修改

    #include <bits/stdc++.h>
    typedef long long LL;
    const int maxn = 500000;
    
    using namespace std;
    
    struct tTree
    {
        LL sum, tag;
        int l, r, len;
    };
    tTree tree[maxn*4+10];
    
    void pushup(int x)
    {
        if (tree[x].l == tree[x].r)
            return;
        tree[x].sum = tree[x*2].sum + tree[x*2+1].sum;
    }
    
    void pushdown(int x)
    {
        if (tree[x].l == tree[x].r)
            return;
        LL tag = tree[x].tag;
        tree[x].tag = 0;
        tree[x*2].sum += tag*tree[x*2].len;
        tree[x*2+1].sum += tag*tree[x*2+1].len;
        tree[x*2].tag += tag;
        tree[x*2+1].tag += tag;
    }
    
    void build(int x, int l, int r)
    {
        tree[x].l = l; tree[x].r = r;
        tree[x].tag = 0;
        tree[x].len = r-l+1;
        if (tree[x].l == tree[x].r)
            scanf("%lld", &tree[x].sum);
        else
        {
            int mid = (l+r)/2;
            build(x*2, l, mid);
            build(x*2+1, mid+1, r);
            pushup(x);
        }
    }
    
    void modify(int x, int l, int r, int val)
    {
        if (tree[x].l>=l && tree[x].r<=r)
        {
            tree[x].tag += val;
            tree[x].sum += val*tree[x].len;
        }
        else
        {
            pushdown(x);
            int mid = (tree[x].l+tree[x].r)/2;
            if (mid >= l)
                modify(x*2, l, r, val);
            if (mid+1 <= r)
                modify(x*2+1, l, r, val);
            pushup(x);
        }
    }
    
    //the sum of the intersection of tree[x].l-tree[x].r and l-r
    LL query(int x, int l, int r)
    {
        if (tree[x].l>=l && tree[x].r<=r)
            return tree[x].sum;
        else
        {
            pushdown(x);
            int mid = (tree[x].l+tree[x].r)/2;
            LL ret = 0;
            if (mid >= l)
                ret += query(x*2, l, r);
            if (mid+1 <= r)
                ret += query(x*2+1, l, r);
            return ret;
        }
    }
    
    int main()
    {
        int N, M;
        scanf("%d%d", &N, &M);
        build(1, 1, N);
        for (int i=1,op,x,y,k; i<=M; i++)
        {
            scanf("%d", &op);
            if (op == 1)
            {
                scanf("%d%d%d", &x, &y, &k);
                modify(1, x, y, k);
            }
            if (op == 2)
            {
                scanf("%d", &x);
                printf("%lld
    ", query(1, x, x));
            }
        }
        return 0;
    }
    

    区间乘加

    #include <bits/stdc++.h>
    typedef long long LL;
    const int maxn = 100000;
    
    using namespace std;
    
    int N, M; LL P;
    
    struct tTree
    {
        LL sum, mul, add;
        int l, r, len;
    };
    tTree tree[maxn*4+10];
    
    void pushup(int x)
    {
        if (tree[x].l == tree[x].r)
            return;
        tree[x].sum = (tree[x*2].sum + tree[x*2+1].sum)%P;
    }
    
    //changes of sum, mul, add
    void pushdown(int x)
    {
        if (tree[x].l == tree[x].r)
            return;
        LL mul = tree[x].mul;
        LL add = tree[x].add;
        tree[x].mul = 1;
        tree[x].add = 0;
        tree[x*2].sum = (tree[x*2].sum*mul%P + add*tree[x*2].len%P)%P;
        tree[x*2+1].sum = (tree[x*2+1].sum*mul%P + add*tree[x*2+1].len%P)%P;
        tree[x*2].mul = tree[x*2].mul*mul%P;
        tree[x*2].add = (tree[x*2].add*mul%P + add)%P;
        tree[x*2+1].mul = tree[x*2+1].mul*mul%P;
        tree[x*2+1].add = (tree[x*2+1].add*mul%P + add)%P;
    }
    
    void build(int x, int l, int r)
    {
        tree[x].l = l; tree[x].r = r;
        tree[x].len = r-l+1;
        tree[x].mul = 1; tree[x].add = 0;
        if (l == r)
            scanf("%lld", &tree[x].sum);
        else
        {
            int mid = (l+r)/2;
            build(x*2, l, mid);
            build(x*2+1, mid+1, r);
            pushup(x);
        }
    }
    
    void modify(int x, int l, int r, int op, int val)
    {
        //keep the sum right
        if (tree[x].l>=l && tree[x].r<=r)
        {
            if (op == 1)
            {
                tree[x].sum = tree[x].sum*val%P;
                tree[x].add = tree[x].add*val%P;
                tree[x].mul = tree[x].mul*val%P;
            }
            if (op == 2)
            {
                tree[x].sum = (tree[x].sum+tree[x].len*val)%P;
                tree[x].add = (tree[x].add+val)%P;
            }
        }
        else
        {
            pushdown(x);
            int mid = (tree[x].l+tree[x].r)/2;
            if (l <= mid)
                modify(x*2, l, r, op, val);
            if (mid+1 <= r)
                modify(x*2+1, l, r, op, val);
            pushup(x);
        }
    }
    
    LL query(int x, int l, int r)
    {
        if (tree[x].l>=l && tree[x].r<=r)
        {
            return tree[x].sum%P;
        }
        else
        {
            pushdown(x);
            int mid = (tree[x].l+tree[x].r)/2;
            LL ret = 0;
            if (l <= mid)
                ret = (ret+query(x*2, l, r))%P;
            if (mid+1 <= r)
                ret = (ret+query(x*2+1, l, r))%P;
            return ret%P;
        }
    }
    
    int main()
    {
        scanf("%d%d%lld", &N, &M, &P);
        build(1, 1, N);
        for (int i=1,op,x,y,k; i<=M; i++)
        {
            scanf("%d", &op);
            if (op == 1)
            {
                scanf("%d%d%d", &x, &y, &k);
                modify(1, x, y, 1, k);
            }
            if (op == 2)
            {
                scanf("%d%d%d", &x, &y, &k);
                modify(1, x, y, 2, k);
            }
            if (op == 3)
            {
                scanf("%d%d", &x, &y);
                printf("%lld
    ", query(1, x, y));
            }
        }
        return 0;
    }
    
    

    区间最大值,无修改

    #include <bits/stdc++.h>
    const int maxn = 100000;
    
    using namespace std;
    
    struct tTree
    {
        int mmax;
        int l, r;
    };
    tTree tree[maxn*4+10];
    
    void pushup(int x)
    {
        if (tree[x].l == tree[x].r)
            return;
        tree[x].mmax = max(tree[x*2].mmax, tree[x*2+1].mmax);
    }
    
    void build(int x, int l, int r)
    {
        tree[x].l = l; tree[x].r = r;
        if (tree[x].l == tree[x].r)
            scanf("%d", &tree[x].mmax);
        else
        {
            int mid = (l+r)/2;
            build(x*2, l, mid);
            build(x*2+1, mid+1, r);
            pushup(x);
        }
    }
    
    int query(int x, int l, int r)
    {
        if (tree[x].l>=l && tree[x].r<=r)
            return tree[x].mmax;
        else
        {
            int mid = (tree[x].l+tree[x].r)/2;
            int ret = -1;
            if (mid >= l)
                ret = max(ret, query(x*2, l, r));
            if (mid+1 <= r)
                ret = max(ret, query(x*2+1, l, r));
            return ret;
        }
    }
    
    int main()
    {
        int N, M;
        scanf("%d%d", &N, &M);
        build(1, 1, N);
        for (int i=1,x,y; i<=M; i++)
        {
            scanf("%d%d", &x, &y);
            printf("%d
    ",query(1, x, y));
        }
        return 0;
    }
    

    三分(凸函数)

    #include <bits/stdc++.h>
    const double eps = 1e-7;
    
    using namespace std;
    
    int N; double l, r;
    double a[20];
    
    double f(double x)
    {
        double ret = 0;
        double tempx = 1;
        for(int i=N+1; i>=1; i--)
        {
            ret += tempx*a[i];
            tempx *= x;
        }
        return ret;
    }
    
    double triSection(double l, double r)
    {
        while (r-l > eps)
        {
            double mid1 = (l*2+r)/3;
            double mid2 = (l+r*2)/3;
            if (f(mid1) < f(mid2))
                l = mid1;
            else
                r = mid2;
        }
        return l;
    }
    
    int main()
    {
        scanf("%d%lf%lf", &N, &l, &r);
        for(int i=1; i<=N+1; i++)
            scanf("%lf", a+i);
        printf("%.5f
    ", triSection(l,r));
        return 0;
    }
    

    快速幂

    LL quickPow(LL a, LL b)
    {
        LL ans = 1, base = a;
        while (b != 0)
        {
            if ((b&1) != 0)
                ans = (ans*base) % mod;
            base = (base*base) % mod;
            b >>= 1;
        }
        return ans;
    }
    
    

    矩阵快速幂

    #include <bits/stdc++.h>
    typedef long long LL;
    const int maxn = 100;
    const LL mod = 1000000007;
    
    using namespace std;
    
    int n; LL k;
    
    struct tMatrix
    {
        LL mat[maxn+10][maxn+10];
        tMatrix()
        {
            memset(mat, 0, sizeof(mat));
        }
        void build()
        {
            for (int i=1; i<=n; i++)
                mat[i][i] = 1;
        }
    };
    
    tMatrix operator*(const tMatrix& a, const tMatrix& b)
    {
        tMatrix c;
        for (int k=1; k<=n; k++)
        for (int i=1; i<=n; i++)
        for (int j=1; j<=n; j++)
        {
            c.mat[i][j] = (c.mat[i][j]+a.mat[i][k]*b.mat[k][j]%mod)%mod;
        }
        return c;
    }
    
    tMatrix quickPowMat(tMatrix a, LL b)
    {
        tMatrix ans; ans.build();
        tMatrix base = a;
        while (b != 0)
        {
            if ((b&1) != 0)
                ans = ans * base;
            base = base * base;
            b >>= 1;
        }
        return ans;
    }
    
    int main()
    {
        scanf("%d%lld", &n, &k);
        tMatrix a;
        for (int i=1; i<=n; i++)
        for (int j=1; j<=n; j++)
        {
            scanf("%lld", &a.mat[i][j]);
        }
        tMatrix ans = quickPowMat(a, k);
        for (int i=1; i<=n; i++)
        for (int j=1; j<=n; j++)
        {
            printf("%lld", ans.mat[i][j]);
            if (j == n)
                printf("
    ");
            else
                printf(" ");
        }
        return 0;
    }
    

    KMP

    #include <bits/stdc++.h>
    const int maxn = 1000000;
    
    using namespace std;
    
    char a[maxn+10], b[maxn+10];
    int la, lb;
    int nxt[maxn+10];
    
    void getNext()
    {
        for (int i=2, j=0; i<=lb; i++)
        {
            while (j && b[j+1]!=b[i])
                j = nxt[j];
            if (b[j+1] == b[i])
                j++;
            nxt[i] = j;
        }
    }
    
    void KMP()
    {
        //j means b[1..j] are successfully matched
        for (int i=1, j=0; i<=la; i++)
        {
            while (j && b[j+1]!=a[i])
                j = nxt[j];
            if (b[j+1] == a[i])
                j++;
            if (j == lb)
            {
                printf("%d
    ", i-lb+1);
                j = nxt[j];
            }
        }
    }
    
    int main()
    {
        scanf("%s%s", a+1, b+1);
        la = strlen(a+1);
        lb = strlen(b+1);
        getNext();
        KMP();
        for (int i=1; i<=lb; i++)
        {
            if (i==lb)
                printf("%d
    ", nxt[i]);
            else
                printf("%d ", nxt[i]);
        }
        return 0;
    }
    

    求逆元

    模为素数

    (p)为素数,(a)为正整数,且(a)(p)互质。则有(a^{p-1}equiv 1(mod p))

    quickPow(a, p-2);
    

    模不为素数

    void exGCD(LL a, LL b, LL &x, LL &y)
    {
        if (!b) x = 1, y = 0;
        else
        {
            exGCD(b, a%b, y, x);
            y -= a/b*x;
        }
    }
    

    求一段逆元

    #include <bits/stdc++.h>
    typedef long long LL;
    const int maxn = 20001000;
    
    using namespace std;
    
    LL inv[maxn+10];
    
    int main()
    {
        LL n, p;
        scanf("%lld%lld", &n, &p);
        inv[1] = 1;
        for (int i=2; i<=n; ++i)
            inv[i] = (p - p / i) * inv[p % i] % p;
        for (int i=1; i<=n; ++i)
            printf("%lld
    ", inv[i]);
        return 0;
    }
    

    LCA

    tarjan离线算法

    #include <bits/stdc++.h>
    const int maxn = 500000;
    const int maxm = 500000;
    
    using namespace std;
    
    int to1[maxn*2+10];
    int nxt1[maxn*2+10];
    int head1[maxn+10], cnt1 = 0;
    
    void addEdge(int x, int y)
    {
        to1[cnt1] = y; nxt1[cnt1] = head1[x];
        head1[x] = cnt1++;
        to1[cnt1] = x; nxt1[cnt1] = head1[y];
        head1[y] = cnt1++;
    }
    
    int to2[maxm*2+10];
    int w2[maxm*2+10];
    int nxt2[maxm*2+10];
    int head2[maxm+10], cnt2 = 0;
    
    void addQuery(int a, int b)
    {
        to2[cnt2] = b; nxt2[cnt2] = head2[a];
        head2[a] = cnt2++;
        to2[cnt2] = a; nxt2[cnt2] = head2[b];
        head2[b] = cnt2++;
    }
    
    int fa[maxn+10];
    int vis[maxn+10];
    
    int getFa(int x)
    {
        if (fa[x] == x)
            return x;
        return fa[x] = getFa(fa[x]);
    }
    
    void LCA(int x, int pre)
    {
        for (int i=head1[x]; i!=-1; i=nxt1[i])
        {
            int l = to1[i];
            if (l != pre)
                LCA(l, x);
        }
        //visit the root last
        for (int i=head2[x]; i!=-1; i=nxt2[i])
        {
            int l = to2[i];
            if (vis[l])
                w2[i] = getFa(l);
        }
        fa[x] = pre;
        vis[x] = 1;
    }
    
    int main()
    {
        int N, M, S;
        scanf("%d%d%d", &N, &M, &S);
        memset(head1, -1, sizeof(head1));
        for (int i=1,x,y; i<=N-1; i++)
        {
            scanf("%d%d", &x, &y);
            addEdge(x, y);
        }
        memset(w2, -1, sizeof(w2));
        memset(head2, -1, sizeof(head2));
        for (int i=1,a,b; i<=M; i++)
        {
            scanf("%d%d", &a, &b);
            addQuery(a, b);
        }
        for (int i=1; i<=N; i++)
            fa[i] = i;
        memset(vis, 0, sizeof(vis));
        LCA(S, S);
        for (int i=0; i<=cnt2-1; i++)
        {
            if (w2[i] != -1)
                printf("%d
    ", w2[i]);
        }
        return 0;
    }
    
    

    FFT

    #include <bits/stdc++.h>
    const int maxn = 10000000;
    const double PI = acos(-1.0);
    
    using namespace std;
    
    struct tComplex
    {
        double x, y;
        tComplex(double xx = 0, double yy = 0)
        {
            x = xx; y = yy;
        }
    };
    tComplex a[maxn+10];
    tComplex b[maxn+10];
    
    tComplex operator + (tComplex a, tComplex b)
    {
        return tComplex(a.x + b.x, a.y + b.y);
    }
    
    tComplex operator - (tComplex a, tComplex b)
    {
        return tComplex(a.x - b.x, a.y - b.y);
    }
    
    tComplex operator * (tComplex a, tComplex b)
    {
        return tComplex(a.x*b.x - a.y*b.y, a.x*b.y + a.y*b.x);
    }
    
    int l, r[maxn+10];
    int limit = 1;
    
    void FFT(tComplex A[], int type)
    {
        for (int i = 0; i < limit; i++)
        {
            if (i < r[i])
                swap(A[i], A[r[i]]);
        }
        for (int mid = 1; mid < limit; mid <<= 1)
        {
            tComplex Wn(cos(PI/mid), type * sin(PI/mid));
            for (int R = mid << 1, j = 0; j < limit; j += R)
            {
                tComplex w(1, 0);
                for (int k = 0; k < mid; k++, w = w * Wn)
                {
                    tComplex x = A[j+k], y = w * A[j+mid+k];
                    A[j+k] = x + y;
                    A[j+mid+k] = x - y;
                }
            }
        }
    }
    
    int main()
    {
        int N, M;
        scanf("%d%d", &N, &M);
        for (int i = 0; i <= N; i++)
            scanf("%lf", &a[i].x);
        for (int i = 0; i <= M; i++)
            scanf("%lf", &b[i].x);
        while (limit <= N+M)
            limit <<= 1, l++;
        // get reverse order 0..limit-1
        for (int i = 0; i < limit; i++)
            r[i] = (r[i>>1]>>1) | ((i&1)<<(l-1));
        FFT(a, 1);
        FFT(b, 1);
        for (int i = 0; i < limit; i++)
            a[i] = a[i] * b[i];
        FFT(a, -1);
        for (int i = 0; i <= N+M; i++)
            printf("%d ", (int)(a[i].x / limit + 0.5));
        return 0;
    }
    
    

    Java大数

    import java.math.BigInteger;
    
    Scanner in = new Scanner(System.in);
    BigInteger x1 = new BigInteger("-11"); //新建一个对象
    BigInteger x2 = in.nextBiginteger();//键盘输入
    BigInteger y = x1.abs(); //取绝对值
    BigInteger y2 = x1.add(y); //x+y
    int x3 = y.compareTo(x1); //x和y比较 < == >分别返回 -1,0,1
    Boolean x4 = (y.compareTo(x1) <= 0); //判断y是否<=x 0是固定不变的,<=符号可以随意变
    BigInteger x5 = y.divide(x1);  // y/x1
    BigInteger x6 = y.multiply(x1);// y*x1
    double x6 = x2.doubleValue(); //将x2转化为double类型,转化为int用intValue()
    BigInteger x7 = x2.gcd(x1);// 返回abs(x2)和abs(x1)的最大公约数
    BigInteger x8 = x2.negate();// 返回-x2
    String x9 = x2.toString();// 将x2转化为字符串
    BigInteger y3 = x2.reamainder(x1);// 返回x2%x1
    BigInteger y4= x1.pow(2);// pow(int exponent) 返回其值为 (this^exponent) 的 BigInteger。
    
    

    去重离散化

    浮点数

    double a[maxn+5];//原数组1..n
    int b[maxn+5];//离散后数组1..n
    
    struct tdisc
    {
        double x;
        int y;
        bool operator<(const tdisc& rhs) const
        {
            return x<rhs.x;
        }
    };
    tdisc disc[maxn+5];//排序用结构体1..n
    
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)//编号1..n
        {
            scanf("%lf",a+i);
            disc[i]=(tdisc){a[i],i};
        }
        sort(disc+1,disc+1+n);
        b[disc[1].y]=1;
        for(int i=2,temp=1;i<=n;i++)
        {
            if(fabs(disc[i].x-disc[i-1].x)>eps)
                temp++;
            b[disc[i].y]=temp;
        }
        return 0;
    }
    

    整数

    int a[maxn+5];//原数组1..n
    int b[maxn+5];//离散后数组1..n
    
    struct tdisc
    {
        int x;
        int y;
        bool operator<(const tdisc& rhs) const
        {
            return x < rhs.x;
        }
    };
    tdisc disc[maxn+5];//排序用结构体1..n
    
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1; i<=n; i++)//编号1..n
        {
            scanf("%d", a+i);
            disc[i] = (tdisc){a[i], i};
        }
        sort(disc+1, disc+1+n);
        b[disc[1].y] = 1;
        for(int i=2, temp=1; i<=n; i++)
        {
            if(disc[i].x > disc[i-1].x)
                temp++;
            b[disc[i].y] = temp;
        }
        for(int i=1; i<=n; i++)
            printf("%d ", b[i]);
        return 0;
    }
    

    Cantor展开

    //s[0..n-1]中存有n个不同的数,返回值从1开始的序号
    int fac[] = {1,1,2,6,24,120,720,5040,40320,362880};
    int cantor(int s[],int n)
    {
        int sum = 0;
        for(int i = 0; i<n; i++)
        {
            int num = 0;
            for(int j=i+1; j<n; j++)
              if(s[j] < s[i])
                num++;
            sum += (num * fac[n-i-1]);
        }
        return sum + 1;
    }
    

    spfa, (O(kE)/O(VE))

    //链式前向星
    int to[maxm*2+10];//maxm指边最大的数目
    int w[maxm*2+10];
    int nex[maxm*2+10];
    int head[maxn+10], cnt;
    
    int dis[maxn+10];//maxn为点最大的数目
    int vis[maxn+10];
    
    queue<int> q; q.push(s);//s为源点
    for(int i=1; i<=n; i++)
    	dis[i] = inf;
    dis[s] = 0; vis[s] = 1;
    while(!q.empty())
    {
    	int p = q.front(); q.pop();
    	vis[p] = 0;
    	for(int i = head[p]; i != -1; i = nex[i])
    	{
            int l = to[i];
            if(dis[l] > dis[p] + w[i])
            {
                dis[l] = dis[p] + w[i];
                if(!vis[l])
                {
                    vis[l] = 1;
                    q.push(l);
                }
            }
        }
    }
    

    dijkstra

    一般实现,(O(V^2))

    int dis[maxn+10];
    int done[maxn+10];
    
    memset(done, 0, sizeof(done));
    for(int i=1; i<=n; i++)
    	dis[i] = inf;
    dis[s] = 0;//s为源点
    for(int i=1; i<=n; i++)
    {
    	int x, m = inf;
    	for(int y=1; y<=n; y++)
    	{
    		if(!done[y] && dis[y]<=m) 
    			m = d[x=y];
    	}
    	done[x] = 1;
    	for(int i = head[x]; i != -1; i = nex[i])
    	{
    		int l = to[i];
    		dis[l] = min(dis[l], dis[x]+w[i]);
    	}
    }
    

    堆优化实现,(O(ElogV))

    struct tnode
    {
        int d,u;//估计的距离,点的编号
        bool operator < (const tnode& rhs) const
        {
            return d > rhs.d;
        }
    };
    int dis[maxn+10];//距离
    int done[maxn+10];//距离是否已确定
    
    int s = 1;//s为源点
    for(int i=1; i<=n; i++)
        dis[i] = inf;
    dis[s] = 0;
    memset(done, 0, sizeof(done));
    priority_queue<tnode> q;
    q.push((tnode){0, s});
    while(!q.empty())
    {
    	tnode x = q.top(); q.pop();
    	int u = x.u;
    	if(done[u])
    		continue;
    	done[u] = 1;
    	for(int i=head[u]; i!=-1; i=nex[i])
    	{
    		int l = to[i];
    		if(dis[l] > dis[u]+w[i])
            {
                dis[l] = dis[u]+w[i];
                q.push((tnode){dis[l], l});
            }
        }
    }
    

    带权并查集

    struct tnode
    {
        int par;
        int rel;//关系
    };
    tnode node[maxn+10];
    
    int parent(int x)
    {
        if(node[x].par != x)
        {
            int temp = node[x].par;
            node[x].par = parent(node[x].par);
            node[x].rel = (node[x].rel+node[temp].rel) % 3;
        }
        return node[x].par;
    }
    
    bool unite(int d,int x,int y)
    {
        int px=parent(x), py=parent(y);		
    	//rel和:px->py应该相当于px->x->y->pyrel
        if(px!=py)
        {
            int temp=-node[x].rel+node[y].rel;
            if(d == 2)
                temp += 1;
            temp = (temp%3+3)%3;//(-1)%3!=2而=-1
            node[px].par = py;
            node[px].rel = temp;
            return true;
        }
        else
        {
            int temp = -node[x].rel+node[y].rel;
            if(d == 2)
                temp += 1;
            temp = (temp%3+3)%3;
            if(temp != 0)
                return false;
            return true;
        }
    }
    

    尾声

    也许还能用到吧,以后的学习。
    算法竞赛,就此终了。
    算法的学习,更广阔的学习,我仍在路上!

  • 相关阅读:
    Mythological VI
    新访问计划
    数学小记
    【Learning】带花树——一般图最大匹配
    朋友
    【bzoj 1414】对称的正方形 单调队列+manacher
    【半集训记录】
    【codeforces 718E】E. Matvey's Birthday
    【codeforces 718 C&D】C. Sasha and Array&D. Andrew and Chemistry
    【bzoj 3233】[Ahoi2013]找硬币 ——搜索
  • 原文地址:https://www.cnblogs.com/acboyty/p/10890959.html
Copyright © 2011-2022 走看看