![]() Rating:1945 | 1.建图 2.数字哈希 3.树分块 4.二分图最大匹配匈牙利算法 5.普通线段树 6.普通并查集 8.树链剖分(点权) 9.最小公倍数&最小公约数 10.树链剖分(边权) 11.组合数打表(求大量组合数) 12.费用流 13.伸展树 以下内容于[2018-08-23 21:13:22]补充 14.最大流 |
![]() 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; } |
![]() 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); }; |
![]() 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; |
![]() 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; } |