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线段树
      • 11单点更新
      • 11成段更新
    • 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