模板

Tab = 3

读入优化

char gc() {
   static char buf[1 << 17], *S, *T;
   if(S == T) T = (S = buf) + fread(buf, 1, 1 << 17, stdin);
   return S == T ? EOF : *S ++;
}
template<class T> void read(T &x) {
   x = 0; char c = gc(); bool na = 0;
   for(; c < '0' || c > '9'; c = gc()) na |= c == '-';
   for(; c >= '0' && c <= '9'; c = gc()) x = x * 10 + (c & 15);
   if(na) x = -x;
}

组合数模板

int C(int n, int m) {
   return n < m ? 0 : 1ll * fac[n] * fav[m] % mod * fav[n - m] % mod;
}
void binom(int n) {
   fac[0] = 1;
   for(int i = 1; i <= n; i ++) fac[i] = 1ll * fac[i - 1] * i % mod;
   fav[n] = qpow(fac[n], mod - 2);
   for(int i = n; i >= 1; i --) fav[i - 1] = 1ll * fav[i] * i % mod;
}

dinic

namespace net {

const int N = 510, M = 4e5 + 10;
struct Edge {
   int v, c, f, nxt;
} e[M];
int ec, hd[N], n;
void init(int _n) {
   n = _n; fill(hd + 1, hd + n + 1, -1); ec = 0;
}
void add(int u, int v, int c) {
   e[ec] = (Edge) {v, c, 0, hd[u]}; hd[u] = ec ++;
   e[ec] = (Edge) {u, 0, 0, hd[v]}; hd[v] = ec ++;
}
int dis[N], cur[N];
bool bfs() {
   fill(dis + 1, dis + n + 1, -1);
   queue<int> q; q.push(1); dis[1] = 0;
   while(q.size()) {
      int u = q.front(); q.pop();
      for(int i = hd[u]; ~ i; i = e[i].nxt) {
         int v = e[i].v;
         if(e[i].f < e[i].c && -1 == dis[v]) {
            dis[v] = dis[u] + 1; q.push(v);
         }
      }
   }
   return ~ dis[n];
}
int dfs(int u, int a) {
   if(u == n || a == 0) return a;
   int ans = 0, f;
   for(int &i = cur[u]; ~ i; i = e[i].nxt) {
      int v = e[i].v;
      if(dis[v] == dis[u] + 1 && (f = dfs(v, min(a, e[i].c - e[i].f))) > 0) {
         ans += f; e[i].f += f; e[i ^ 1].f -= f;
         if((a -= f) == 0) break ;
      }
   }
   return ans;
}
int dinic() {
   int ans = 0;
   while(bfs()) {
      copy(hd + 1, hd + n + 1, cur + 1);
      ans += dfs(1, INF);
   }
   return ans;
}

}

倍增lca

f[u][0] = fa; d[u] = d[fa] + 1;
for(int i = 1; i < lgn; i ++)
   f[u][i] = f[f[u][i - 1]][i - 1];

int lca(int u, int v) {
   if(d[u] < d[v]) swap(u, v);
   int c = d[u] - d[v];
   for(int i = lgn - 1; ~ i; i --)
      if(c >> i & 1) u = f[u][i];
   if(u == v) return u;
   for(int i = lgn - 1; ~ i; i --)
      if(f[u][i] ^ f[v][i]) {
         u = f[u][i]; v = f[v][i];
      }
   return f[u][0];
}

for(lgn = 1; (1 << lgn) <= n; lgn ++) ;

建图 + 最短路

namespace G {

const int M = N;
struct Edge { int v, w; };
vector<Edge> G[M];
struct Node {
   int u, d;
   bool operator < (const Node &b) const {
      return d > b.d;
   }
};
int n;
void init(int _n) {
   n = _n;
}
void link(int u, int v, int w) {
   G[u].push_back((Edge) {v, w});
}
void Dijkstra(int s, int *d) {
   fill(d + 1, d + n + 1, INF);
   priority_queue<Node> pq; pq.push((Node) {s, d[s] = 0});
   while(pq.size()) {
      int u = pq.top().u, du = pq.top().d; pq.pop();
      if(d[u] < du) continue ;
      for(int i = 0; i < (int) G[u].size(); i ++) {
         Edge &e = G[u][i];
         if(d[e.v] > d[u] + e.w) {
            d[e.v] = d[u] + e.w; pq.push((Node) {e.v, d[e.v]});
         }
      }
   }
}

}

fft

const db pi = 2 * acos(-1);
struct comp {
   db x, y;
   comp() {}
   comp(db a, db b) : x(a), y(b) {}
   comp operator + (const comp &b) const { return comp(x + b.x, y + b.y); }
   comp operator - (const comp &b) const { return comp(x - b.x, y - b.y); }
   comp operator * (const comp &b) const { return comp(x * b.x - y * b.y, b.x * y + x * b.y); }
} W[N], A[N], B[N];
int len, rev[N];
void init(int n) {
   int k = 0;
   for(len = 1; len <= n; len <<= 1) k ++;
   for(int i = 1; i < len; i ++)
      rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (k - 1));
   for(int i = 0; i < len; i ++)
      W[i] = comp(cos(pi * i / len), sin(pi * i / len));
}
void fft(comp *a, int ty) {
   for(int i = 1; i < len; i ++)
      if(i < rev[i]) swap(a[i], a[rev[i]]);
   static comp t1, t2;
   for(int i = 1; i < len; i <<= 1) {
      for(int j = 0; j < len; j += i << 1) {
         for(int k = j; k < j + i; k ++) {
            t1 = a[k], t2 = W[len / (i << 1) * (k - j)] * a[k + i];
            a[k] = t1 + t2; a[k + i] = t1 - t2;
         }
      }
   }
   if(ty == -1) {
      reverse(a + 1, a + len);
      for(int i = 0; i < len; i ++)
         a[i].x /= len, a[i].y /= len;
   }
}

纯NTT

int rev[N], len, w[N], inv_w[N];
void InitNTT(int n) {
   int k = 0;
   for(len = 1; len <= n; len <<= 1) k ++;
   for(int i = 1; i < len; i ++)
      rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (k - 1));
   w[0] = inv_w[0] = 1;
   int v = qpow(_g, (mod - 1) / len);
   for(int i = 1; i < len; i ++)
      inv_w[len - i] = w[i] = 1ll * w[i - 1] * v % mod;
}
void NTT(int *a, const int *w) {
   for(int i = 1; i < len; i ++)
      if(i < rev[i]) swap(a[i], a[rev[i]]);
   for(int i = 1; i < len; i <<= 1) {
      for(int j = 0, t = len / (i << 1); j < len; j += i << 1) {
         const int *wn = w;
         for(int k = j; k < j + i; k ++, wn += t) {
            int t1 = a[k], t2 = 1ll * *wn * a[k + i] % mod;
            a[k] = (t1 + t2) % mod; a[k + i] = (t1 - t2 + mod) % mod;
         }
      }
   }
   if(w == inv_w) {
      int v = mod - (mod - 1) / len;
      for(int i = 0; i < len; i ++)
         a[i] = 1ll * a[i] * v % mod;
   }
}

二维st表

#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 1003;
int n, m, lg[N], a[N][N][10][10];
short b[N][N];
int query(int x1, int y1, int x2, int y2) {
   int k1 = lg[x2 - x1 + 1], k2 = lg[y2 - y1 + 1];
   return max(max(a[x1][y1][k1][k2], a[x2 - (1 << k1) + 1][y1][k1][k2]), 
      max(a[x1][y2 - (1 << k2) + 1][k1][k2], a[x2 - (1 << k1) + 1][y2 - (1 << k2) + 1][k1][k2]));
}
int main() {
   scanf("%d%d", &n, &m);
   for(int i = 1; i <= n; i ++) {
      for(int j = 1; j <= m; j ++) {
         scanf("%hd", &b[i][j]);
         if(b[i][j]) a[i][j][0][0] = min(a[i - 1][j][0][0], min(a[i][j - 1][0][0], a[i - 1][j - 1][0][0])) + 1;
      }
   }
   for(int i = 2; i <= max(n, m); i ++) lg[i] = lg[i >> 1] + 1;
   for(int i = 1; i <= lg[m]; i ++) {
      for(int x = 1; x <= n; x ++) {
         for(int y = 1; y + (1 << i) - 1 <= m; y ++) {
            a[x][y][0][i] = max(a[x][y][0][i - 1], a[x][y + (1 << (i - 1))][0][i - 1]);
         }
      }
   }
   for(int i = 1; i <= lg[n]; i ++) {
      for(int j = 0; j <= lg[m]; j ++) {
         for(int x = 1; x + (1 << i) - 1 <= n; x ++) {
            for(int y = 1; y + (1 << j) - 1 <= m; y ++) {
               a[x][y][i][j] = max(a[x][y][i - 1][j], a[x + (1 << (i - 1))][y][i - 1][j]);
            }
         }
      }
   }
   int t; scanf("%d", &t);
   while(t --) {
      int x1, y1, x2, y2;
      scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
      int l = 1, r = min(x2 - x1 + 1, y2 - y1 + 1), ans = 0;
      while(l <= r) {
         int mid = (l + r) >> 1;
         if(query(x1 + mid - 1, y1 + mid - 1, x2, y2) >= mid) l = (ans = mid) + 1;
         else r = mid - 1;
      }
      printf("%d\n", ans);
   }
   return 0;
}
posted @ 2020-03-02 13:14  hfhongzy  阅读(15)  评论(0编辑  收藏  举报