cantaloupebulid by [参赛达人]哈密瓜 at 2018-08-14 20:50
Rating:1945

1.建图

2.数字哈希

3.树分块

4.二分图最大匹配匈牙利算法

5.普通线段树

6.普通并查集

8.树链剖分(点权)

9.最小公倍数&最小公约数

10.树链剖分(边权)

11.组合数打表(求大量组合数)

12.费用流

13.伸展树


以下内容于[2018-08-23 21:13:22]补充

14.最大流

11 reply by [参赛达人]哈密瓜 at 2018-08-19 20:46
Rating:1945
///求大量组合数
const ll mod = 1000000007;
ll fac[2*maxn+10];
ll invfac[2*maxn+10];
ll q_pow(ll a,ll b)
{
    ll ans=1;
    while(b)
    {
        if(b&1) ans=a*ans%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
void init()
{
    fac[0]=1;
    for(int i=1;i<=2*maxn;i++)
        fac[i]=fac[i-1]*i%mod;
    invfac[2*maxn]=q_pow(fac[2*maxn],mod-2);
    for(int i=2*maxn-1;i>=0;i--)
        invfac[i]=invfac[i+1]*(i+1)%mod;
}
inline ll C(int n,int m)
{
    if(n<m)
        return 0;
    if(n==m)
        return 1;
    return fac[n]*invfac[n-m]%mod*invfac[m]%mod;
}


12 reply by [参赛达人]哈密瓜 at 2018-08-22 19:10
Rating:1945
///费用流
struct MCMF
{
    static const int MAXN = 50100;
    static const int MAXM = 5001000;
    static const int INF = 0x7FFFFFFF;
    static const int INF0X3F = 0x3f3f3f3f;
    int n, m, first[MAXN], s, t, sign;
    int dist[MAXN], inq[MAXN], pre[MAXN], incf[MAXN];
    int max_flow, min_cost;

    struct Edge
    {
        int to, cap, cost, next;
    } edge[MAXM * 4];

    void init(int l, int r, int ss, int tt)
    {
        //for(int i = l; i <= r; i++ ){first[i] = -1;}
        memset(first, -1, sizeof(first));
        s = ss, t = tt, sign = 0;
        max_flow = min_cost = 0;
    }

    void add_edge(int u, int v, int cap, int cost)
    {
        edge[sign].to = v, edge[sign].cap = cap, edge[sign].cost = cost;
        edge[sign].next = first[u], first[u] = sign++;
        edge[sign].to = u, edge[sign].cap = 0, edge[sign].cost = -cost;
        edge[sign].next = first[v], first[v] = sign++;
    }

    bool spfa(int s, int t)
    {
        for(int i = 0; i < MAXN; i++ )
        {
            dist[i] = INF, inq[i] = 0;
        }
        queue<int>que;
        que.push(s), inq[s] = 1, dist[s] = 0;
        incf[s] = INF0X3F;
        while(!que.empty())
        {
            int now = que.front();
            que.pop();
            inq[now] = 0;
            for(int i = first[now]; ~i; i = edge[i].next)
            {
                int to = edge[i].to, cap = edge[i].cap, cost = edge[i].cost;
                if(cap > 0 && dist[to] > dist[now] + cost)
                {
                    dist[to] = dist[now] + cost;
                    incf[to] = min(incf[now], cap);
                    pre[to] = i;
                    if(!inq[to])
                    {
                        que.push(to);
                        inq[to] = 1;
                    }
                }
            }
        }
        return dist[t] != INF;
    }
    void update(int s, int t)
    {
        int x = t;
        while(x != s)
        {
            int pos = pre[x];
            edge[pos].cap -= incf[t];
            edge[pos ^ 1].cap += incf[t];
            x = edge[pos ^ 1].to;
        }
        max_flow += incf[t];
        min_cost += dist[t] * incf[t];
    }
    void minCostMaxFlow(int s, int t)
    {
        while(spfa(s, t))
        {
            update(s, t);
        }
    }
} p;

void solve()
{
    /// 0 源点
    /// m+m+1 次源点
    /// m+m+2 汇点
    int n, m, K, W;
    scanf("%d %d %d %d", &n, &m, &K, &W);
    p.init(0, m+m+2 , 0, m+m+2);  ///初始化 l,r,开始点,结束点

    /*
    * 建图
    */
    ///权值取负
    p.minCostMaxFlow(0, m+m+2);
    printf("%d\n", -p.min_cost);
};


13 reply by [参赛达人]哈密瓜 at 2018-08-23 00:53
Rating:1945
///splay
///插入一个元素
///前驱
///后继
///找x的排名
///找排名为x的数字
///删除
struct Splay_Tree
{
    struct Node
    {
        int father, childs[2], key, cnt, _size;
        inline void init()
        {
            father = childs[0] = childs[1] = key = cnt = _size = 0;
        }
        inline void init(int father, int lchild, int rchild, int key, int cnt, int sz)
        {
            this -> father = father, childs[0] = lchild, childs[1] = rchild;
            this -> key = key, this -> cnt = cnt, _size = sz;
        }
    } tre[maxn];
    int sign, root;
    int tot;  ///种树

    inline void init()
    {
        sign = root = tot = 0;
    }

    inline bool judge(int x)
    {
        return tre[ tre[x].father ].childs[1] == x;
    }

    inline void update(int x)
    {
        if(x)
        {
            tre[x]._size = tre[x].cnt;
            if(tre[x].childs[0])
            {
                tre[x]._size += tre[ tre[x].childs[0] ]._size;
            }
            if(tre[x].childs[1])
            {
                tre[x]._size += tre[ tre[x].childs[1] ]._size;
            }
        }
    }

    inline void rotate(int x)
    {
        int y = tre[x].father, z = tre[y].father, k = judge(x);

        //tre[y].childs[k] = tre[x].childs[!k], tre[ tre[x].childs[!k] ].father = y;
        //tre[x].childs[!k] = y, tre[y].father = x;
        //tre[z].childs[ tre[z].childs[1] == y ] = x, tre[x].father = z;

        if(k == 0)   ///zig
        {
            tre[y].childs[0] = tre[x].childs[1], tre[ tre[x].childs[1] ].father = y;
            tre[x].childs[1] = y, tre[y].father = x;
        }
        else     ///zag
        {
            tre[y].childs[1] = tre[x].childs[0], tre[ tre[x].childs[0] ].father = y;
            tre[x].childs[0] = y, tre[y].father = x;
        }
        tre[z].childs[ tre[z].childs[1] == y ] = x, tre[x].father = z;

        update(y);
    }

    inline void splay(int x,int goal)
    {
        for(int father; (father = tre[x].father) != goal; rotate(x) )
        {
            if(tre[father].father != goal)
            {
                rotate(judge(x) == judge(father) ? father : x);
            }
        }
        root = x;
    }

    inline void insert_node(int x)  ///插入一个元素
    {
        tot++;
        if(root == 0)
        {
            tre[++sign].init(0, 0, 0, x, 1, 1);
            root = sign;
            return ;
        }
        int now = root, father = 0;
        while(1)
        {
            if(tre[now].key == x)
            {
                tre[now].cnt ++;
                update(now), update(father);
                splay(now, 0);
                break;
            }
            father = now;
            if(x > tre[now].key)
            {
                now = tre[now].childs[1];
            }
            else
            {
                now = tre[now].childs[0];
            }
            if(now == 0)
            {
                tre[++sign].init(father, 0, 0, x, 1, 1);
                if(x > tre[father].key)
                {
                    tre[father].childs[1] = sign;
                }
                else
                {
                    tre[father].childs[0] = sign;
                }
                update(father);
                splay(sign, 0);
                break;
            }
        }
    }
    inline int pre()    ///前驱
    {
        int now = tre[root].childs[0];
        while(tre[now].childs[1])
        {
            now = tre[now].childs[1];
        }
        return now;
    }

    inline int next()   ///后继
    {
        int now = tre[root].childs[1];
        while(tre[now].childs[0])
        {
            now = tre[now].childs[0];
        }
        return now;
    }

    inline int find_rank(int x)   /// 找x的排名
    {
        int now = root, ans = 0;
        while(1)
        {
            if(x < tre[now].key)
            {
                now = tre[now].childs[0];
            }
            else
            {
                if(tre[now].childs[0])
                {
                    ans += tre[ tre[now].childs[0] ]._size;
                }
                if(x == tre[now].key)
                {
                    splay(now, 0);
                    return ans + 1;
                }
                ans += tre[now].cnt;
                now = tre[now].childs[1];
            }
        }
    }

    inline int find_rankx(int x)   /// 找排名为x的数字
    {
        int now = root;
        while(1)
        {
            if(tre[now].childs[0] && x <= tre[ tre[now].childs[0] ]._size )
            {
                now = tre[now].childs[0];
            }
            else
            {
                int lchild = tre[now].childs[0], sum = tre[now].cnt;
                if(lchild)
                {
                    sum += tre[lchild]._size;
                }
                if(x <= sum)
                {
                    return tre[now].key;
                }
                x -= sum;
                now = tre[now].childs[1];
            }
        }
    }

    inline void del(int x)   ///删除
    {
        tot--;
        find_rank(x);
        if(tre[root].cnt > 1)
        {
            tre[root].cnt --;
            update(root);
            return ;
        }
        if(!tre[root].childs[0] && !tre[root].childs[1])
        {
            tre[root].init();
            root = 0;
            return ;
        }
        if(!tre[root].childs[0])
        {
            int old_root = root;
            root = tre[root].childs[1], tre[root].father = 0, tre[old_root].init();
            return ;
        }
        if(!tre[root].childs[1])
        {
            int old_root = root;
            root = tre[root].childs[0], tre[root].father = 0, tre[old_root].init();
            return ;
        }
        int pre_node = pre(), old_root = root;
        splay(pre_node, 0);
        tre[root].childs[1] = tre[old_root].childs[1];
        tre[ tre[old_root].childs[1] ].father = root;
        tre[old_root].init();
        update(root);
    }

    inline bool find(int x)
    {
        int now = root;
        while(1)
        {
            if(now == 0)
            {
                return 0;
            }
            if(x == tre[now].key)
            {
                splay(now, 0);
                return 1;
            }
            if(x > tre[now].key)
            {
                now = tre[now].childs[1];
            }
            else
            {
                now = tre[now].childs[0];
            }
        }
    }

} S;


14 reply by [参赛达人]哈密瓜 at 2018-08-23 21:13
Rating:1945
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define inf 0x3fffffff
using namespace std;
const int maxn=600;
int first[maxn],sign,cur[maxn];
int s,t,d[maxn];
int mp[maxn][maxn];
struct node
{
    int to,w,next;
} edge[maxn*50];
void creat()
{
    memset(first,-1,sizeof(first));
    sign=0;
}
void add_edge(int u,int v,int w)
{
    edge[sign].to=v;
    edge[sign].w=w;
    edge[sign].next=first[u];
    first[u]=sign++;

    edge[sign].to=u;
    edge[sign].w=0;
    edge[sign].next=first[v];
    first[v]=sign++;
}
int bfs()
{
    queue<int>q;
    memset(d,0,sizeof(d));
    d[s]=1;
    q.push(s);
    while(!q.empty())
    {
        int top=q.front();
        q.pop();
        for(int i=first[top]; ~i; i=edge[i].next)
        {
            int to=edge[i].to;
            if(edge[i].w>0&&d[to]==0)
            {
                d[to]=d[top]+1;
                if(to==t)
                    return 1;
                q.push(to);
            }
        }
    }
    return d[t]!=0;
}
int dfs(int top,int flow)
{
    if(top==t)
        return flow;
    int ans=0,x=0;
    for(int i=cur[top]; ~i; i=edge[i].next)
    {
        int to=edge[i].to;
        if(edge[i].w>0&&d[to]==d[top]+1)
        {
            x=dfs(to,min(flow-ans,edge[i].w));
            edge[i].w-=x;
            edge[i^1].w+=x;
            if(edge[i].w)
                cur[top] = i;
            ans+=x;
            if(ans==flow)
                return flow;
        }
    }
    if(ans==0)
        d[top]=0;
    return ans;
}
int dinic(int n)
{

    int ans=0;
    while(bfs())
    {
        for(int i=0; i<=n; i++)
            cur[i]=first[i];
        ans+=dfs(s,inf);
    }
    return ans;
}
int a[500],b[500];
int main()
{
    creat();
    return 0;
}


回复
要回复,请先登录

T^T Online Judge

[BUG反馈] [FAQ] [闽ICP备17026590号-1]
当前版本:3.24 系统时间: