ACM个人模板
来源:互联网 发布:vs2017 golang 编辑:程序博客网 时间:2024/04/28 21:48
- 图论
- 1最小生成树
- 11 Kruskal
- 12Prim
- 2最短路径
- 21 SPFA
- 22Dijkstra
- 23Floyd
- 3网络流
- 31Dinic
- 32预流推进
- 33Ford最裸的
- 34费用流
- 4二分图匹配
- 41匈牙利算法
- 5连通性问题
- 51Tarjan
- 6拓扑排序
- 7A算法
- 1最小生成树
- 数据结构
- 1线段树
- 11单点更新
- 11成段更新
- 1字典树
- 1线段树
- 计算几何
- 1求凸包
- 2求直线相交
- 字符串
- 1KMP
1. 图论
1.1最小生成树
1.1.1 Kruskal
说明:并查集是优化过的
struct Edge { int u, v, weight; }; Edge edges[MAX_SIZE*MAX_SIZE]; int nodeNum, edgeNum, pre[MAX_SIZE], pos1[MAX_SIZE], pos2[MAX_SIZE]; //pos1,pos2保存以连接的2个点。 void FUset(){ for(int i=1;i<=500000;i++) pre[i]=i;}int Find(int x){ return pre[x]==x?x:Find(pre[x]);}void Union(int x,int y){ x=Find(x); y=Find(y); if(x==y) return ; pre[x]=y;}bool cmp(Edge a, Edge b) { return a.weight < b.weight; } int Kruskal(int &buildEdgeNum) { int i, u, v, maxWeight; sort(edges, edges + edgeNum, cmp); FUset(); buildEdgeNum = 0; for(i = 0; i < edgeNum; i++){ u = Find(edges[i].u); v = Find(edges[i].v); if(u != v){ maxWeight = edges[i].weight; Union(u, v); pos1[buildEdgeNum] = edges[i].u; pos2[buildEdgeNum] = edges[i].v; buildEdgeNum++; } if(buildEdgeNum >= nodeNum - 1) break; } return maxWeight; }
1.1.2.Prim
int Prim(int start) { int i, j, minEdge, res, v; for(i = 0; i < nodeNum; i++) lowCost[i] = graph[start][i]; lowCost[start] = -1; res = 0; for(i = 1; i < nodeNum; i++){ minEdge = INF; for(j = 0; j < nodeNum; j++) if(lowCost[j] != -1 && lowCost[j] < minEdge){ minEdge = lowCost[j]; v = j; } lowCost[v] = -1; res += minEdge; for(j = 0; j < nodeNum; j++) if(lowCost[j] > graph[v][j]) lowCost[j] = graph[v][j]; } return res; }
1.2.最短路径
1.2.1. SPFA
//有负环返回 false, 否则返回 true bool spfa() { int dist[MAX_SIZE], cnt[MAX_SIZE] = {0}, i, j, cur; bool inQue[MAX_SIZE] = {0}; queue <int> que; //设0为起点 for(i = 1; i <= nodeNum; i++) dist[i] = (1 == i? 0:INF); que.push(1); inQue[1] = true; cnt[1]++; while(!que.empty()){ cur = que.front(); inQue[cur] = false; que.pop(); for(i = 1; i <= nodeNum; i++){ if(dist[i] > dist[cur] + graph[cur][i]){ dist[i] = dist[cur] + graph[cur][i]; if(cnt[i] > nodeNum-1) return false; if(!inQue[i]){ que.push(i); inQue[i] = true; cnt[i]++; } } } } return true; }
1.2.2.Dijkstra
void Dijkstra(int startPos, int dist[]) { int i, j, minPath, nextPos; bool visited[MAX_SIZE] = {0}; //initialize first vertex visited[startPos] = true; for(i = 1; i <= numOfVertex; i++){ if(graph[startPos][i] > 0 && !visited[i]){ dist[i] = graph[startPos][i]; } else{ dist[i] = INF; } } dist[startPos] = 0; for(i = 2; i <= numOfVertex; i++){ minPath = INF; //find minPath for(j = 1; j <= numOfVertex; j++){ if(dist[j] < minPath && !visited[j]){ minPath = dist[j]; startPos = j; } } //move visited[startPos] = true; for(j = 1; j <= numOfVertex; j++){ if(graph[startPos][j] > 0 && !visited[j] && minPath + graph[startPos][j] < dist[j] ){ dist[j] = minPath + graph[startPos][j]; } } } }
1.2.3.Floyd
double Floyd() { int i, j, k; for(k = 0; k < nodeNum; k++) for(i = 0; i < nodeNum; i++) for(j = 0; j < nodeNum; j++) graph[i][j] = min(graph[i][j], max(graph[i][k], graph[k][j])); return graph[0][1]; }
1.3.网络流
1.3.1.Dinic
说明:求最小点割集
1.有向图:把一个点拆成(i, i+N)2个点,之间容量为1。如果i, j2个点在原图中联通,则将i+N,j相连,容量为无穷大。然后求最小割,可见被最小割割到的都是容量是1的边,(如果割到一条INF,说明没有最小点割集。)而且那些边必将连着i,i+N,于是i就是被割的点。
2.无向图:把一个点拆成(i, i+N)2个点,之间容量为1。如果i, j2个点在原图中联通,则将i+N,j相连,容量为无穷大。则将j, i+N相连,容量为无穷大。以下如上。
class Dinic { public: struct Edge { int v, w, next; }; int cnt, head[MAX_N*2], dist[MAX_N*2], s, t; Edge edges[MAX_N*MAX_N*2]; void init(int is, int it) { cnt = 0; s = is, t = it; memset(head, -1, sizeof(head)); } void addEdge(int u, int v, int weight) { edges[cnt] = (Edge){v, weight, head[u]}; head[u] = cnt++; edges[cnt] = (Edge){u, 0, head[v]}; head[v] = cnt++; } bool BFS() { int i, cur; queue <int> que; que.push(s); memset(dist, -1, sizeof(dist)); dist[s] = 0; while(!que.empty()){ cur = que.front(); que.pop(); for(i = head[cur]; i != -1; i = edges[i].next) if(-1 == dist[edges[i].v] && edges[i].w){ dist[edges[i].v] = dist[cur] + 1; que.push(edges[i].v); } } return dist[t] != -1; } int DFS(int start, int curFlow) { if(start == t) return curFlow; int i, minFlow = 0, v, temp; for(i = head[start]; i != -1; i = edges[i].next){ v = edges[i].v; if(dist[start] == dist[v] - 1 && edges[i].w > 0){ temp = DFS(v, min(edges[i].w, curFlow)); edges[i].w -= temp; edges[i^1].w += temp; curFlow -= temp; minFlow += temp; if(0 == curFlow) break; } } if(0 == minFlow) dist[start] = -2; return minFlow; } int maxFlow() { int res = 0; while(BFS()){ res += DFS(s, INF); } return res; } }G; bool edges[MAX_N][MAX_N]; int edgeNum, nodeNum; int netFlow(int s, int t) { G.init(s + nodeNum, t); int i, j; for(i = 0; i < nodeNum; i++){ G.addEdge(i, i + nodeNum, 1); for(j = 0; j < nodeNum; j++) if(edges[i][j]) G.addEdge(i + nodeNum, j, INF); } return G.maxFlow(); } int S, T, N, mp[MAX_N][MAX_N], saveMap1[MAX_N], saveMap2[MAX_N]; int buildGraph() { int i, j; Dinic G; G.init(S+N, T); for(i = 1; i <= N; i++) G.addEdge(i, i + N, 1); for(i = 1; i <= N; i++) for(j = 1; j <= N; j++) if(i != j && 1 == mp[i][j]) G.addEdge(i + N, j, INF); return G.maxFlow(); }
1.3.2.预流推进
class Push_Relabel { public: struct node { int x, h; bool friend operator <(const node &a,const node &b) { return a.h<b.h; } }; struct Edge { int v, weigt, next; }; Edge edges[MAX_M*MAX_M]; int s, t, maxFlow, cnt, head[MAX_M], H[MAX_M], EF[MAX_M]; priority_queue <node> que; void init(int is, int it, int nodeNum) { memset(edges, 0, sizeof(edges)); memset(H, 0, sizeof(H)); memset(EF, 0, sizeof(EF)); memset(head, -1, sizeof(head)); maxFlow = 0; cnt = 0; s = is, t = it; EF[s] = INF; EF[t] = -INF; H[s] = nodeNum; } void addEdge(int u, int v, int weight) { edges[cnt] = (Edge){v, weight, head[u]}; head[u] = cnt++; edges[cnt] = (Edge){u, 0, head[v]}; head[v] = cnt++; } void Push(int cur) { int i, temp, v; node tmp; for(i = head[cur]; i != -1; i = edges[i].next){ v = edges[i].v; temp = min(edges[i].weigt, EF[cur]); if(temp > 0 &&(cur == s || 1==H[cur]-H[v])){ edges[i].weigt -= temp, edges[i^1].weigt += temp; EF[cur] -= temp, EF[v] += temp; if(v == t) maxFlow += temp; if(v != s && v != t){ tmp.x = v, tmp.h = H[v]; que.push(tmp); } } } } void Relabel(int cur) { node tmp; if(cur != s && cur != t && EF[cur] > 0){ H[cur]++; tmp.h = H[cur], tmp.x = cur; que.push(tmp); } } int ans() { node cur{s, H[s]}; que.push(cur); while(!que.empty()){ cur = que.top(); que.pop(); Push(cur.x); Relabel(cur.x); } return maxFlow; } }G; int low[MAX_M][MAX_M], up[MAX_M][MAX_M], cnt[MAX_M], row, col, s, t; bool ableSolve; void init() { ableSolve = true; s = row + col + 1, t = s + 1; memset(cnt, 0, sizeof(cnt)); memset(low, 0, sizeof(low)); memset(up, INF, sizeof(up)); G.init(t + 1, t + 2, t + 2); }
1.3.3.Ford(最裸的)
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> #include <vector> #include <string> using namespace std; const int INF = 0x3f3f3f3f, MAX_N = 109, MAX_M = 1008; int N, M, s, t; int capacity[MAX_N][MAX_N], flow[MAX_N][MAX_N]; void buildGraph() { int i, j, key, keyNum, pigNum[MAX_M], pre[MAX_M]; cin>>M>>N; memset(pre, 0, sizeof(pre)); s = 0, t = N + 1; for(i = 1; i <= M; i++) cin>>pigNum[i]; for(i = 1; i <= N; i++){ cin>>keyNum; for(j = 1; j <= keyNum; j++){ cin>>key; if(0 == pre[key]) capacity[s][i] += pigNum[key]; else capacity[ pre[key] ][i] = INF; pre[key] = i; } cin>>capacity[i][t]; } } void Ford() { int i, j, cur, save, preV[MAX_N], flag[MAX_N], minFlow[MAX_N]; queue <int> que; while(1){ memset(flag, -1, sizeof(flag)); memset(preV, -1, sizeof(preV)); while(!que.empty()) que.pop(); que.push(0); minFlow[0] = INF; flag[0] = 0; while(!que.empty() && flag[t] == -1){ cur = que.front(); que.pop(); for(i = 0; i <= N+1; i++){ save = capacity[cur][i] - flow[cur][i]; if(-1 == flag[i] && save > 0){ preV[i] = cur; minFlow[i] = min(minFlow[cur], save); flag[i] = 0; que.push(i); } } flag[cur] = 1; } if(-1 == flag[t]) break; for(i = preV[t], j = t; i != -1; j = i, i = preV[i]){ flow[i][j] += minFlow[t]; flow[j][i] = -flow[i][j]; } } for(i = 0, save = 0; i < t; i++) save += flow[i][t]; cout<<save<<endl; } int main() { //freopen("in.txt", "r", stdin); buildGraph(); Ford(); return 0; }
1.3.4.费用流
#include <iostream>#include <cstdio>#include <queue>#include <cstring>#include <cstdlib>using namespace std;const int INF = 0x3f3f3f3f, MAX_SIZE = 1000;class AdjList{public: int *head, cnt; struct Edge { int cost, cap, v, next; }*edges; AdjList() { edges = new Edge[MAX_SIZE*MAX_SIZE]; head = new int[MAX_SIZE]; cnt = 0; memset(head, -1, sizeof(int)*MAX_SIZE); } ~AdjList() { delete[] edges; delete[] head; } void addEdge(int u, int v, int cap, int cost) { edges[cnt].v = v, edges[cnt].cap = cap, edges[cnt].cost = cost, edges[cnt].next = head[u]; head[u] = cnt++; edges[cnt].v = u, edges[cnt].cap = 0, edges[cnt].cost = -cost, edges[cnt].next = head[v]; head[v] = cnt++; }};class MinCost{public: AdjList G; int *dist, *pre, *path, s, t; MinCost() { dist = new int[MAX_SIZE]; pre = new int[MAX_SIZE]; path = new int[MAX_SIZE]; } ~MinCost() { delete[] dist; delete[] pre; delete[] path; } bool SPFA() { bool inQue[MAX_SIZE]; queue <int> que; int cur, v, i; memset(dist, INF, sizeof(int)*MAX_SIZE); memset(inQue, 0, sizeof(inQue)); memset(pre, -1, sizeof(int)*MAX_SIZE); dist[s] = 0; que.push(s); inQue[s] = true; while(!que.empty()){ cur = que.front(); que.pop(); inQue[cur] = false; for(i = G.head[cur]; i != -1; i = G.edges[i].next){ v = G.edges[i].v; if(G.edges[i].cap && dist[v] > dist[cur] + G.edges[i].cost){ dist[v] = dist[cur] + G.edges[i].cost; pre[v] = cur; path[v] = i; if(!inQue[v]){ que.push(v); inQue[v] = true; } } } } return pre[t] != -1; } int ford_fulkerson(int &maxFlow) { int sum = 0, u, v, minFlow, i; maxFlow = 0; while(SPFA()){ minFlow = INF; for(u = pre[t], v = t; u != -1; v = u, u = pre[u]){ i = path[v]; minFlow = min(minFlow, G.edges[i].cap); } maxFlow += minFlow; for(u = pre[t], v = t; u != -1; v = u, u = pre[u]){ i = path[v]; G.edges[i].cap -= minFlow; G.edges[i^1].cap += minFlow; sum += minFlow*G.edges[i].cost; } } return sum; }};const int MAX_N = 58;int N, M, K, orders[MAX_N][MAX_N], supply[MAX_N][MAX_N], cost[MAX_N][MAX_N][MAX_N];int getMinCost(int foodId){ MinCost poj2516; int i, j, s, t, maxFlow, sumOrder, res; s = M+N+1, t = M+N+2; poj2516.s = s, poj2516.t = t; sumOrder = 0; for(i = 1; i <= M; i++) poj2516.G.addEdge(s, i, supply[i][foodId], 0); for(i = 1; i <= N; i++){ poj2516.G.addEdge(i + M, t, orders[i][foodId], 0); sumOrder += orders[i][foodId]; } for(i = 1; i <= M; i++) for(j = 1; j <= N; j++) poj2516.G.addEdge(i, j+M, INF, cost[foodId][j][i]); res = poj2516.ford_fulkerson(maxFlow); if(sumOrder != maxFlow) return -1; else return res;}int main(){ //freopen("in.txt", "r", stdin); int i, j, t, temp, sum; while(~scanf("%d%d%d", &N, &M, &K) && (N+M+K)){ for(i = 1; i <= N; i++) for(j = 1; j <= K; j++) scanf("%d", &orders[i][j]); for(i = 1; i <= M; i++) for(j = 1; j <= K; j++) scanf("%d", &supply[i][j]); for(t = 1; t <= K; t++) for(i = 1; i <= N; i++) for(j = 1; j <= M; j++) scanf("%d", &cost[t][i][j]); sum = 0; for(t = 1; t <= K; t++){ temp = getMinCost(t); if(temp != -1) sum += temp; else{ sum = -1; break; } } printf("%d\n", sum); } return 0;}
1.4.二分图匹配
1.4.1.匈牙利算法
class maxMatch { public: bool connected[MAX_SIZE][MAX_SIZE], visited[MAX_SIZE]; int xMatch[MAX_SIZE], yMatch[MAX_SIZE], xNum, yNum; void init() { xNum = yNum = 0; memset(connected, 0, sizeof(connected)); memset(xMatch, -1, sizeof(xMatch)); memset(yMatch, -1, sizeof(yMatch)); } bool path(int u) { int v; for(v = 1; v <= yNum; v++) if(connected[u][v] && !visited[v]){ visited[v] = true; if(-1 == yMatch[v] || path(yMatch[v])){ yMatch[v] = u; xMatch[u] = v; return true; } } return false; } int getRes() { int i, res = 0; for(i = 1; i <= xNum; i++) if(-1 == xMatch[i]){ memset(visited, 0, sizeof(visited)); if(path(i)) res++; } return res; } }G;
1.5.连通性问题
1.5.1.Tarjan
说明:给一个网络,节点与节点相连,让你求去掉某些节点能不能使得整个网络不联通
class Tarjan { public: vector <int> edges[MAX_SIZE]; int low[MAX_SIZE], dfn[MAX_SIZE], root, maxNode, subnetsNum[MAX_SIZE]; bool visited[MAX_SIZE], isNode[MAX_SIZE], isSPF[MAX_SIZE], found; void init() { int i; for(i = 0; i < MAX_SIZE; i++) edges[i].clear(); found = false; memset(subnetsNum, 0, sizeof(subnetsNum)); memset(isNode, 0, sizeof(isNode)); memset(visited, 0, sizeof(visited)); memset(isSPF, 0, sizeof(isSPF)); maxNode = 0; } void addEdge(int u, int v) { edges[u].push_back(v); edges[v].push_back(u); maxNode = max(maxNode, max(u, v)); isNode[u] = isNode[v] = true; } void dfs(int u, int depth) { visited[u] = true; low[u] = dfn[u] = depth; int i, v; for(i = 0; i < edges[u].size(); i++){ v = edges[u][i]; if(!visited[v]){ if(u == root) subnetsNum[root]++; dfs(v, depth + 1); if(u != root) low[u] = min(low[u], low[v]); if(low[v] >= dfn[u] && u!= root){ isSPF[u] = true; subnetsNum[u]++; found = true; } } else low[u] = min(low[u], dfn[v]); } } void startDFS() { for(root = 1; root <= maxNode; root++) if(isNode[root]) break; dfs(root, 1); if(subnetsNum[root] > 1){ isSPF[root] = true; subnetsNum[root]--; found = true; } } }G;
1.6拓扑排序
void TopoSort() { int i, cur; queue <int> que; for(i = 0; i < nodeNum; i++) if(0 == cnt[i]){ que.push(i); Ee[i] = 1; } while(!que.empty()){ cur = que.front(); que.pop(); for(i = 0; i < graph[cur].size(); i++){ if(0 == --cnt[graph[cur][i].v]) que.push(graph[cur][i].v); Ee[graph[cur][i].v] = max(Ee[cur] + graph[cur][i].weight, Ee[graph[cur][i].v]); } } }
1.7.A*算法
//POJ2449import java.util.*;class Main { final static int MAX_SIZE = 1010; final static int INF = 0x3f3f3f3f; static class Node{ public int v; public int weight; } static List<Node> Graph[] = new ArrayList[MAX_SIZE]; static List<Node> reGraph[] = new ArrayList[MAX_SIZE]; static int nodeNum; static int edgeNum; static int k; static int[] SPFA(int start, int end){ int dist[] = new int[nodeNum+1]; boolean inQue[] = new boolean[nodeNum+1]; Queue<Integer> que = new LinkedList<Integer>(); int i, cur; for (i = 0; i < nodeNum+1; i++){ dist[i] = INF; inQue[i] = false; } dist[start] = 0; que.offer(start); inQue[start] = true; while (!que.isEmpty()) { cur = que.poll(); inQue[cur] = false; Iterator<Node> it = reGraph[cur].iterator(); while (it.hasNext()){ Node node = it.next(); int v = node.v; int weight = node.weight; if (dist[v] > dist[cur] + weight){ dist[v] = dist[cur] + weight; if (!inQue[v]){ inQue[v] = true; que.offer(v); } } } } return dist; } static int AStar(int start, int end, int []H){ class Point{ public int id; public int h; public int g; } Comparator<Point> order = new Comparator<Point>(){ public int compare(Point a, Point b){ int fa = a.g + a.h; int fb = b.g + b.h; return fa>fb? 1:(fa==fb?0:-1); } }; Queue<Point> que = new PriorityQueue<Point>(nodeNum, order); Point cur = new Point(); cur.g = 0; cur.h = H[start]; cur.id = start; que.offer(cur); int cnt = 0; while(!que.isEmpty()){ cur = que.poll(); if (cur.id == end){ cnt++; if (cnt == k){ return cur.g + cur.h; } } Iterator<Node> it = Graph[cur.id].iterator(); while(it.hasNext()){ Node tmp = it.next(); int v = tmp.v; int weight = tmp.weight; Point nextP = new Point(); nextP.g = cur.g + weight; nextP.h = H[v]; nextP.id = v; que.offer(nextP); } } return -1; } public static void main(String[] args) { Scanner in = new Scanner(System.in); nodeNum = in.nextInt(); edgeNum = in.nextInt(); int u, v, w, i; for (i = 1; i <= nodeNum; i++) Graph[i] = new ArrayList<Node>(); for (i = 1; i <= nodeNum; i++) reGraph[i] = new ArrayList<Node>(); for (i = 0; i < edgeNum; i++){ u = in.nextInt(); v = in.nextInt(); w = in.nextInt(); Node newNode = new Node(); newNode.v = v; newNode.weight = w; Graph[u].add(newNode); //反向图 Node newNodeForRe = new Node(); newNodeForRe.v = u; newNodeForRe.weight = w; reGraph[v].add(newNodeForRe); } int start, end; start = in.nextInt(); end = in.nextInt(); k = in.nextInt(); int dist[] = SPFA(end, start); if (start == end) k++; System.out.println(AStar(start, end, dist)); in.close(); }}
2.数据结构
2.1线段树
2.1.1.单点更新
#define LC(t) t<<1 #define RC(t) t<<1|1 struct node { int l, r, cnt; }; node seTree[4*MAX_N]; void build(int l, int r, int idx) { seTree[idx].l = l; seTree[idx].r = r; seTree[idx].cnt = 0; if(l == r) return; int mid = (l+r)>>1; build(l, mid, LC(idx)); build(mid+1, r, RC(idx)); } void add(int idx, int pos, int num) { int l = seTree[idx].l, r = seTree[idx].r; if(l <= pos && r >= pos){ seTree[idx].cnt += num; if(l == r) return; add(LC(idx), pos, num); add(RC(idx), pos, num); } } int query(int l, int r, int idx) { int lSide = seTree[idx].l, rSide = seTree[idx].r; if(lSide == l && rSide == r) return seTree[idx].cnt; int mid = (lSide+rSide)>>1; if(lSide <= l && mid >= r) return query(l, r, LC(idx)); if(mid+1 <= l && rSide >= r) return query(l, r, RC(idx)); if(lSide <= l && rSide >= r){ return query(l, mid, LC(idx)) + query(mid+1, r, RC(idx)); } }
2.1.1.成段更新
#include <cstdio>#include <cmath>using namespace std;const int MAX_N = 100100;const int INF = 0x3f3f3f3f;#define LC(t) t<<1#define RC(t) t<<1|1struct node{ int l, r; int mid() { return l+r >> 1; }}seTree[4*MAX_N];long long add[MAX_N<<2],sum[MAX_N<<2];void build(int nd, int l, int r){ seTree[nd].l = l; seTree[nd].r = r; sum[nd] = add[nd] = 0; if(l == r) return; int mid = seTree[nd].mid(); build(LC(nd), l, mid); build(RC(nd), mid+1, r);}void pushDown(int nd, int len){ if(!add[nd]) return; add[LC(nd)] += add[nd]; add[RC(nd)] += add[nd]; sum[LC(nd)] += add[nd]*(len -(len>>1)); sum[RC(nd)] += add[nd]*(len>>1); add[nd] = 0;}void pushUp(int nd){ sum[nd] = sum[LC(nd)] + sum[RC(nd)];}void upDate(int nd, int l, int r,int ele){ if(l == seTree[nd].l && r ==seTree[nd].r){ sum[nd] += ele*(r-l+1); add[nd] += ele; return; } if(seTree[nd].l == seTree[nd].r) return; pushDown(nd, seTree[nd].r-seTree[nd].l+1); int mid = seTree[nd].mid(); if(r <= mid) upDate(LC(nd), l, r, ele); else if(l > mid) upDate(RC(nd), l, r, ele); else{ upDate(LC(nd), l, mid, ele); upDate(RC(nd), mid+1, r, ele); } pushUp(nd);}long long query(int nd, int l,int r){ if(seTree[nd].l == l &&seTree[nd].r == r) return sum[nd]; pushDown(nd, seTree[nd].r-seTree[nd].l+1); int mid = seTree[nd].mid(); if(r <= mid) return query(LC(nd), l, r); if(l > mid) return query(RC(nd), l, r); return query(LC(nd), l, mid) +query(RC(nd), mid+1, r);}int main(){ //freopen("in.txt","r", stdin); int N, Q, i, ele, a, b, c; char ch; while(~scanf("%d%d", &N,&Q)){ build(1, 1, N); for(i = 1; i <= N; i++){ scanf("%d", &ele); upDate(1, i, i, ele); } for(i = 1; i <= Q; i++){ scanf("\n%c %d %d",&ch, &a, &b); if(ch == 'C'){ scanf("%d", &c); upDate(1, a, b, c); } else printf("%I64d\n",query(1, a, b)); } } return 0;}
2.1.字典树
#include <cstdio> #include <cstring> using namespace std; const int MAX_N = 26; const int INF = 0x3f3f3f3f; struct node { int cnt; node* next[MAX_N]; }heap[500000], root; int top; node *newNode() { return &heap[top++]; } void addNode(char *str) { int len = strlen(str), i; node *p = &root, *q; for(i = 0; i < len; i++){ int key = str[i] - 'a'; if(p->next[key] == NULL){ q = newNode(); q->cnt = 1; memset(q->next, 0, sizeof(q->next)); p->next[key] = q; p = p->next[key]; } else{ p = p->next[key]; p->cnt++; } } } int Find(char *str) { node *p = &root; int i, key; for(i = 0; str[i]; i++){ key = str[i]-'a'; if(p->next[key] == NULL) return 0; p = p->next[key]; } return p->cnt; } int main() { //freopen("in.txt", "r", stdin); char tmp[12]; while(gets(tmp) && tmp[0]) addNode(tmp); while(~scanf("%s", tmp)) printf("%d\n", Find(tmp)); return 0; }
3.计算几何
3.1.求凸包
import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.Comparator;import java.util.List;import java.util.Scanner;import java.util.Stack;class Main { static final int MAX_SIZE = 1050; static final double INF = 1e40; static final double ESP = 1e-4; static int vertexNum; static double length; static List<Point> points = new ArrayList<Point>(); static Point base; static Stack<Point> s; static double cross(Vector v1, Vector v2){ return v1.x*v2.y - v2.x*v1.y; } static double pointDist(Point p1, Point p2){ return Math.sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y)); } static void sortPoints(){ Collections.sort(points, new Comparator(){ @Override public int compare(Object arg0, Object arg1) { Point p1 = (Point)arg0; Point p2 = (Point)arg1; Vector v1 = new Vector(); Vector v2 = new Vector(); v1.setXY(base, p1); v2.setXY(p1, p2); double res = cross(v1, v2); if(res > 0){ return -1; }else if(res == 0){ return (pointDist(p1, base) > pointDist(p2, base)? 1:-1); }else{ return 1; } } }); } static void findConvexHull(){ s = new Stack<Point>(); s.push(points.get(0)); s.push(points.get(1)); s.push(points.get(2)); for(int i = 3; i < vertexNum; i++){ while(true){ Point beJudged = s.pop(); Point begin = s.peek(); Vector v1 = new Vector(), v2 = new Vector(); v1.setXY(begin, beJudged); v2.setXY(beJudged, points.get(i)); if(cross(v1, v2)>=0){ s.push(beJudged); break; } } s.push(points.get(i)); } } public static void main (String args[]){ Scanner in = new Scanner(System.in); double x, y; while(in.hasNext()){ vertexNum = in.nextInt(); length = in.nextDouble(); int baseIdx = 0; points.removeAll(points); for(int i = 0; i < vertexNum; i++){ x = in.nextDouble(); y = in.nextDouble(); Point p = new Point(); p.setXY(x, y); points.add(p); if(points.get(baseIdx).y > y || points.get(baseIdx).y == y && points.get(baseIdx).x > x){ baseIdx = i; } } base = points.get(baseIdx); sortPoints(); findConvexHull(); double res = pointDist(base, s.peek()); while(s.size() > 1){ Point p = s.pop(); res += pointDist(p, s.peek()); } Point p = s.pop(); res += pointDist(p, base); res += 2*Math.PI*length; System.out.println(Math.round(res)); } in.close(); }}class Point{ public void setXY(double x, double y) { this.x = x; this.y = y; } public double x, y;}class Vector{ public void setXY(Point begin, Point end) { this.x = end.x-begin.x; this.y = end.y-begin.y; } public Vector reVector() { Vector v = new Vector(); v.x = -x; v.y = -y; return v; } public double x, y;}
3.2.求直线相交
import java.util.Scanner;class Main { static final int MAX_SIZE = 110; static class Point{ double x, y; } //输入向量(x1, y1), (x2, y2) static double crossProduct(double x1, double y1, double x2, double y2){ return x1*y2- x2*y1; } //parameter[] ={a, b, c} 直线:ax+by+c=0 static void getLine(Point p1, Point p2, double[]parameter){ parameter[0] = p1.y- p2.y; parameter[1] = p2.x -p1.x; parameter[2] = p1.x*p2.y - p2.x*p1.y; } public static void main (String args[]){ Scanner in = new Scanner(System.in); int test = in.nextInt(); Point []p = new Point[4]; for (int i = 0; i < 4; i++){ p[i] = new Point(); } double [][] parameter = new double[2][3]; double a1, a2, b1, b2, c1, c2; System.out.println("INTERSECTING LINES OUTPUT"); while(test-- != 0){ for (int i = 0; i < 4; i++){ p[i].x = in.nextDouble(); p[i].y = in.nextDouble(); } getLine(p[0], p[1], parameter[0]); getLine(p[2], p[3], parameter[1]); a1 = parameter[0][0]; b1 = parameter[0][1]; c1 = parameter[0][2]; a2 = parameter[1][0]; b2 = parameter[1][1]; c2 = parameter[1][2]; double D1 = b2*(-c1)-b1*(-c2), D2 = a1*(-c2)-a2*(-c1), D = a1*b2 - a2*b1; if (D == 0 && D1 == 0 && D2 == 0){ System.out.println("LINE"); } else if (D == 0){ System.out.println("NONE"); } else { double x = D1/D; double y = D2/D; System.out.printf("POINT %.2f %.2f \n", x, y); } } System.out.println("END OF OUTPUT"); in.close(); }}
4.字符串
4.1KMP
#include <cstdio>#include <algorithm>#include <cstring>using namespace std;const int MAX_N = 10100, INF = 0x3f3f3f3f;int Next[MAX_N];char pattern[MAX_N], match[1000100];void getNext(){ int i, k; Next[0] = 0; for(i = 1; pattern[i]; i++){ k = Next[i-1]; while(pattern[i] != pattern[k] && k > 0) k = Next[k-1]; if(pattern[i] == pattern[k]) Next[i] = k+1; else Next[i] = 0; }}int KMP(){ getNext(); int i = 0, j = 0, cnt = 0; while(match[i]){ while(j > 0 && pattern[j] != match[i]) j = Next[j-1]; if(pattern[j] == match[i]) i++, j++; else i++; if(!pattern[j]){ cnt++; j = Next[j-1]; } } return cnt;}int main(){ //freopen("in.txt", "r", stdin); int T; scanf("%d", &T); while(T--){ scanf("%s%s", pattern, match); printf("%d\n", KMP()); } return 0;}
0 0
- ACM个人模板
- ACM练级日志:Treap个人用模板
- ACM模板(个人代码集整理)(持续更新)
- acm模板
- acm模板
- ACM模板
- ACM模板
- ACM 模板
- ACM 模板
- acm 模板
- ACM模板
- ACM 模板
- ACM模板
- ACM模板
- ACM模板
- ACM---模板
- acm 模板
- ACM模板
- KVO
- C++中的enum类型
- java 基础运算
- 【SSH网上商城项目实战27】域名空间的申请和项目的部署及发布
- 记录自己有用的链接
- ACM个人模板
- NSNotification
- C++之多重继承
- express框架持久化
- SQL多表查询
- PAT_1015. Reversible Primes
- ACM-NYOJ-算法赛题-喷水装置1
- 蓝桥杯模拟赛-还款计算
- 来谈谈毕业快两年的工作感受