ACM模板

1、快速读入
ll read(){
    ll ret = 0;bool fl = 0;
    char ch = getchar();
    while(ch < '0' || ch > '9') {if(ch == '-') fl = 1;ch = getchar();}
    while(ch >= '0' && ch <= '9') ret = ret * 10 + ch - '0', ch = getchar();
    return fl ? -ret : ret;
}
2、java大整数
import java.util.*;

//import com.sun.xml.internal.ws.api.server.AbstractServerAsyncTransport;

import java.math.*;

public class Main{
    public static void main(String args[]){
        Scanner cin = new Scanner(System.in);
        String str1, str2;
        String a;
        BigDecimal A, B;
        double b;
        while(cin.hasNext()) {
            str1 = cin.next();
            if(str1.charAt(0) == '1') {
                System.out.println(str1 + " [8] = " + "1" + " [10]");
                continue;
            }
            str2 = str1.substring(2, str1.length());
            //System.out.println(str2);
            BigInteger c = new BigInteger(str2, 8);
            a = c.toString(10);
            A = new BigDecimal(a);
            for(int i = 0; i < str2.length(); i++) {
                A = A.divide(BigDecimal.valueOf(8));
            }
            System.out.println(str1 + " [8] = " + A + " [10]");
        }
    }
}
3、线性筛
void Prime(){
    for(int i = 2; i <= n; i++)
        isprime[i] = 1;
    for(int i = 2; i <= n; i++){
        if(isprime[i]) prime[++cnt] = i, phi[i] = i - 1;
        for(int j = 1; j <= cnt && prime[j] * i <= n; j++){
            isprime[prime[j] * i] = 0;
            if(i % prime[j] == 0){
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            }
            else phi[i * prime[j]] = phi[i] * (prime[j] - 1);
        }
    }
}
4、扩展欧几里得
void exgcd(ll a, ll b, ll &d, ll &x, ll &y) {
    if(!b) {d = a; x = 1; y = 0; return;}
    exgcd(b, a % b, d, y, x); y -= x * (a / b);
}
5、中国剩余定理

(普通)
……留坑
(扩展)

ll excrt() {
    ll M = m[1], R = r[1], d, x, y;
    for(int i = 2; i <= n; i++) {
        exgcd(M, m[i], d, x, y);
        if((R - r[i]) % d) return -1;
        x = (R - r[i]) / d * x % m[i];
        R -= M * x;
        M = M * m[i] / d;
        R %= M;
    }
    return (R % M + M) % M;
}
6、BM算法
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define rep(i,a,n) for (int i=a;i=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector VI;
typedef long long ll;
typedef pair PII;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod;  for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
// head

int _,n;
namespace linear_seq {
    const int N=100010;
    ll res[N],base[N],_c[N],_md[N];

    vector Md;
    void mul(ll *a,ll *b,int k) {
        rep(i,0,k+k) _c[i]=0;
        rep(i,0,k) if (a[i]) rep(j,0,k) _c[i+j]=(_c[i+j]+a[i]*b[j])%mod;
        for (int i=k+k-1;i>=k;i--) if (_c[i])
            rep(j,0,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
        rep(i,0,k) a[i]=_c[i];
    }
    int solve(ll n,VI a,VI b) { // a 系数 b 初值 b[n+1]=a[0]*b[n]+...
//        printf("%d\n",SZ(b));
        ll ans=0,pnt=0;
        int k=SZ(a);
       // assert(SZ(a)==SZ(b));
        rep(i,0,k) _md[k-1-i]=-a[i];_md[k]=1;
        Md.clear();
        rep(i,0,k) if (_md[i]!=0) Md.push_back(i);
        rep(i,0,k) res[i]=base[i]=0;
        res[0]=1;
        while ((1ll<=0;p--) {
            mul(res,res,k);
            if ((n>>p)&1) {
                for (int i=k-1;i>=0;i--) res[i+1]=res[i];res[0]=0;
                rep(j,0,SZ(Md)) res[Md[j]]=
                (res[Md[j]]-res[k]*_md[Md[j]])%mod;
            }
        }
        rep(i,0,k) ans=(ans+res[i]*b[i])%mod;
        if (ans<0) ans+=mod;
        return ans;
    }
    VI BM(VI s) {
        VI C(1,1),B(1,1);
        int L=0,m=1,b=1;
        rep(n,0,SZ(s)) {
            ll d=0;
            rep(i,0,L+1) d=(d+(ll)C[i]*s[n-i])%mod;
            if (d==0) ++m;
            else if (2*L<=n) {
                VI T=C;
                ll c=mod-d*powmod(b,mod-2)%mod;
                while (SZ(C) num;
    int p[100] ={
31,
197,
1255,
7997,
50959,
324725,
};
    for(int i=0;i<6;i++)
        num.push_back(p[i]);
    linear_seq::init(num);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ll n;
        scanf("%lld",&n); n--;
        printf("%d\n",linear_seq::gao(num,n-1));
    }
    return 0;
}
7、莫比乌斯反演
#include
#include
#define N 100005
#define ll long long
using namespace std;
bool p[N]={1,1};
int prime[N],mu[N],sum[N],cnt,t,a,b,c,d,k;
void getmu(){
    mu[1]=1; cnt=0;
    for(int i = 2; i < N; i++){
        if(!p[i]){
            prime[++cnt]=i;
            mu[i]=-1;
        }
        for(int j = 1; j <= cnt && i * prime[j] < N; j++){
            p[i * prime[j]] = 1;
            if(i % prime[j] == 0){
                mu[i * prime[j]] = 0;
                break;
            }
            mu[i * prime[j]] = -mu[i];
        }
    }
    for(int i = 1;i < N; i++) sum[i] = sum[i-1] + mu[i];
    //for(int i=1;i<100;i++) printf("%d\n",mu[i]);
}
ll getans(int n,int m){
    ll ret = 0;
    if(n > m) swap(n, m);
    for(int i = 1, last; i <= n; i = last + 1){
        last = min(n / (n / i), m / (m / i));
        ret += (ll)(n / i) * (ll)(m / i)*(ll)(sum[last] - sum[i-1]);
    }
    return ret;
}
int main(){
    scanf("%d", &t);
    getmu();
    for(int i = 1; i <= t; i++){
        scanf("%d%d%d%d%d", &a, &b, &c, &d, &k);
        if(k == 0) printf("Case %d: %lld\n", i, 0);
        else printf("Case %d: %lld\n", i, getans(b / k, d / k));
    }
    return 0;
}
8、splay
struct SPLAY{
    int val[N], sz[N], fa[N], ch[N][2], cnt[N], root, tot;
    void update(int x){
        sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + cnt[x];
    }
    void debug(){
        for(int i = 1; i <= 10; i++)
            printf("%d %d %d %d %d\n", i, ch[i][0], ch[i][1], sz[i], cnt[i]);
    }
    void Rotate(int x){
        int y = fa[x], z = fa[y];
        int k = (ch[y][1] == x);
        ch[z][ch[z][1] == y] = x;
        fa[x] = z;
        ch[y][k] = ch[x][k ^ 1];
        fa[ch[y][k]] = y;
        ch[x][k ^ 1] = y;
        fa[y] = x;
        update(y); update(x);
    }
    void splay(int x, int pos){
        while(fa[x] != pos){
            int y = fa[x], z = fa[y];
            if(z != pos)
                ((ch[z][0] == y) ^ (ch[y][0] == x)) ? Rotate(x) : Rotate(y);
            Rotate(x);
        }
        if(pos == 0) root = x;
        update(x);
    }
    void Insert(int x){
        int u = root, ff = 0;
        while(u && val[u] != x){
            ff = u;
            u = ch[u][x > val[u]];
        }
        if(u) {cnt[u]++; splay(u, 0); return;}
        u = ++tot;
        if(ff) ch[ff][x > val[ff]] = u;
        ch[u][0] = ch[u][1] = 0;
        fa[u] = ff;
        val[u] = x;
        cnt[u] = 1;
        sz[u] = 1;
        splay(u, 0);
    }
    void Find(int x){
        int u = root;
        if(!u) return;
        while(ch[u][x > val[u]] && x != val[u])
            u = ch[u][x > val[u]];
        splay(u, 0);
        //printf("%d\n", u);
    }
    int Next(int x, int f){
        Find(x);
        //debug();
        int u = root;
        if(val[u] > x && f) return u;
        if(val[u] < x && !f) return u;
        u = ch[u][f];// printf("%d\n", u);
        while(ch[u][f ^ 1]) u = ch[u][f ^ 1];
        return u;
    }
    void Delete(int x){
        int last = Next(x, 0);
        int next = Next(x, 1);
        splay(last, 0);splay(next, last); //debug();
        sz[next]--;sz[last]--;
        int del = ch[next][0];
        if(cnt[del] > 1){
            sz[del]--;
            cnt[del]--;
            splay(del, 0);
        }
        else ch[next][0] = 0;
        //debug();
    }
    int Rank(int x){
        Find(x);
        return sz[ch[root][0]];
    }
    int kth(int k){
        k++;
        int u = root, now = 0;
        while(1){
            if(ch[u][0] && k <= sz[ch[u][0]]) u=ch[u][0];
            else{
                int tmp = sz[ch[u][0]] + cnt[u];
                if(k <= tmp) return val[u];
                k -= tmp;
                u = ch[u][1];
            }
        }
    }
};
SPLAY Splay;
9、prim

留坑

10、dijkstra
void dijkstra(int s, int o, int k){
    for(int i = 1; i <= n; i++) dis[i][k] = 1e18;
    memset(vis, 0, sizeof(vis));
    dis[s][k] = 0;
    q.push(mp(0, s));
    while(!q.empty()){
        ll d = q.top().fi;
        int x = q.top().se;
        q.pop();
        if(vis[x]) continue;
        vis[x] = 1;
        for(int t = idx[x]; t; t = edge[t].nxt){
            E e = edge[t];
            if(d + e.w < dis[e.to][k]){
                dis[e.to][k] = d + e.w;
                q.push(mp(dis[e.to][k], e.to));
            }
        }
    }
}
11、spfa
void SPFA(){
    q.push(s);vis[s]=1;
    memset(dis,127,sizeof(dis));
    dis[s]=0;
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int t=idx[x];t;t=edge[t].nxt){
            E e=edge[t];
            if(dis[e.to]>dis[x]+e.w){
                dis[e.to]=dis[x]+e.w;
                if(!vis[e.to]){
                    vis[e.to]=1;
                    q.push(e.to);
                }
            }
        }
        vis[x]=0;
    }
}
12、线段树
#include 
#define ll long long
#define N 100005 * 4
#define mid ((l + r) >> 1)
#define L k << 1, l, mid
#define R k << 1 | 1, mid + 1, r
#define O k, l, r
using namespace std;
ll sum[N],tag[N],a[N];
int n,m;
ll read(){
    char ch;ll x = 0; bool f = 0;
    for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = 1;
    for(;'0' <= ch && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
    if(f) return -x; return x;
}
void paint(int k, int l, int r, ll z){
    sum[k] += z * (r - l + 1);
    tag[k] += z;
}
void pushup(int k){
    sum[k] = sum[k << 1] + sum[k << 1 | 1];
}
void pushdown(int k, int l, int r){
    paint(L, tag[k]);
    paint(R, tag[k]);
    tag[k] = 0;
}
void build(int k, int l, int r){
    if(l == r){
        sum[k] = a[l];
        tag[k] = 0;
        return;
    }
    build(L);build(R);
    pushup(k);return;
}
void add(int k, int l, int r, int x, int y, ll z){
    if(x <= l && r <= y){
        paint(O, z);
        return;
    }
    pushdown(O);
    if(x <= mid) add(L, x, y, z);
    if(mid + 1 <= y) add(R, x, y ,z);
    pushup(k); return;
}
ll query(int k, int l, int r, int x, int y){
    if(x <= l && r <= y) return sum[k];
    ll ans = 0;
    pushdown(O);
    if(x <= mid) ans += query(L, x, y);
    if(mid + 1 <= y) ans += query(R, x, y);
    pushup(k);
    return ans;
}
int main(){
    while(scanf("%d%d", &n, &m) == 2){
        for(int i = 1; i <= n * 4; i++)
            sum[i] = tag[i] = 0;
        for(int i = 1; i <= n; i++)
            a[i] = read();

        build(1, 1, n);
        for(int i = 1, x, y, z; i <= m; i++){
            char c = getchar();
            if(c == 'C'){
                x = read();
                y = read();
                z = read();
                add(1, 1, n, x, y, z);
            }
            if(c == 'Q'){
                x = read();
                y = read();
                printf("%lld\n", query(1, 1, n, x, y));
            }
        }
    }
    return 0;
}
13、kmp
void getnext(){
    memset(f, 0, sizeof(f));
    f[1] = 0; int j = 0; num[1] = 1;
    for(int i = 2;i <= la; i++){
        while(j && s1[i] != s1[j + 1]) j = f[j];
        if(s1[i] == s1[j + 1]) j++;
        f[i] = j;
        num[i] = num[f[i]] + 1;
    }
    //for(int i = 1; i <= la; i++) printf("%d : %lld ", i, num[i]);puts("");
}
void kmp(){

    int j = 0;
    for(int i = 2;i <= la; i++){
        while(j && s1[i] != s1[j + 1]) j = f[j];
        if(s1[i] == s1[j + 1]) j++;
        while(j * 2 > i) j = f[j];
        //printf("%d\n", j);
        ans = ans * (num[j] + 1) % Mo;
    }//puts("");
}
14、manacher
void manacher(){
    ans = 0;
    for(int i = 1; i <= l + l + 1; i++)
        if(i & 1) s[i] = '%';
        else s[i] = s1[i / 2];
    f[1] = 1; R = 1; pos = 1; l = l + l + 1;
    for(int i = 1; i <= l; i++){
        if(i <= R) f[i] = min(f[pos * 2 - i], R - i);
        else f[i] = 1;
        while(i - f[i] >= 1 && i + f[i] <= l && s[i - f[i]] == s[i + f[i]]) f[i]++;
        if(i + f[i] > R) {pos = i; R = i + f[i];}
    }
}
15、set
#include 
#include 
#include 
using namespace std;
const int N = 200005;
const int inf = 0x7fffffff;
struct Node{
    int id, val;
};
bool operator < (const Node a, const Node b){
    return a.val < b.val;
}
set  s;
int q, x, y;
char opt;
int main(){
    while(scanf("%d", &opt) && opt){
        if(opt == 1){
            scanf("%d%d", &x, &y);
            s.insert((Node){x, y});
        }
        if(opt == 2){
            if(s.empty()) {printf("0\n"); continue;}
            printf("%d\n", (*(--s.end())).id);
            s.erase(--s.end());
        }
        if(opt == 3){
            if(s.empty()) {printf("0\n"); continue;}
            printf("%d\n", (*s.begin()).id);
            s.erase(s.begin());
        }
    }
    return 0;
}

16、km算法

#include 
#include 
#include 
using namespace std;
const int N = 20005;
const int M = 100005;
struct E {int to, nxt;}edge[M];
bool vis[N];
int left[N], idx[N], tot, n, m, x, y, ans;
struct A{int x, y;} a[N];
bool operator < (A l, A r){return l.x < r.x;}
void addedge(int from, int to){
    from++; to++;
    //printf("%d %d\n", from, to);
    edge[++tot].to = to;edge[tot].nxt = idx[from]; idx[from] = tot;
}
bool dfs(int x){
    for(int t = idx[x]; t; t = edge[t].nxt){
        E e = edge[t];
        if(vis[e.to]) continue;
        vis[e.to] = 1;
        if(!left[e.to] || dfs(left[e.to])){
            left[e.to] = x;
            return 1;
        }
    }

    return 0;
}
int main() {
    scanf("%d", &n); m = n;
    for(int i = 0; i < n; i++){
        scanf("%d", &x);
        if(x > n / 2) {printf("No Answer\n");return 0;}
        x = n - x;
        if(i + x < n) addedge(i, i + x + n);
        x = n - x;
        if(i + x < n) addedge(i, i + x + n);
        if(i - x >= 0) addedge(i, i - x + n);
        x = n - x;
        if(i - x >= 0) addedge(i, i - x + n);
    }
    for(int i = n; i >= 1; i--){
        memset(vis, 0, sizeof(vis));
        ans += dfs(i);
    }
    //printf("%d\n", ans);
    //for(int i = 1; i <= m; i++) printf("%d %d\n", left[i + n], i);
    if(ans != n) {printf("No Answer\n");return 0;}
    for(int i = 1; i <= m; i++)
        a[i].x = left[i + n], a[i].y = i;
    sort(a + 1, a + 1 + m);
    for(int i = 1; i < m; i++)
        printf("%d ", a[i].y - 1);
    printf("%d\n", a[m].y - 1);
    return 0;
}

17、dinic

void init(){
    memset(idx, 0, sizeof(idx));
    memset(a, 0, sizeof(a));
    memset(cur, 0, sizeof(0));
    tot = 2;
     S = 1; T = n;
    for(int i=1, x, y, w; i <= m; i++)
        scanf("%d%d%d", &x, &y, &w),
        addedge(x, y, w, 0), addedge(y, x, 0, 0);
}
bool BFS(){
    memset(vis, 0, sizeof(vis));
    memset(dis, 0, sizeof(dis));
    Q.push(S); vis[S] = 1;
    while(!Q.empty()){
        int x = Q.front(); Q.pop();
        for(int t = idx[x]; t; t = edge[t].nxt){
            E& e = edge[t];
            if(!vis[e.to] && e.cap > e.flow) {
                vis[e.to] = 1;
                Q.push(e.to);
                dis[e.to] = dis[x] + 1;
            }
        }
    }
    return vis[T];
}
int DFS(int x, int a){
    int flow=0, f;
    if(x == T || a == 0) return a;
    for(int& i = cur[x]; i; i = edge[i].nxt){
        E& e = edge[i];
        if(dis[x] + 1 == dis[e.to]){
            f=DFS(e.to, min(a,e.cap - e.flow));
            if(f > 0){
                edge[i].flow += f;
                edge[i ^ 1].flow -= f;
                flow += f;
                a -= f;
                if(!a) break;
            }
        }
    }
    return flow;
}
int dinic(){
    int flow=0;
    while(BFS()){
        for(int i = 0;i <= n; i++) cur[i] = idx[i];
        flow += DFS(S, INF);

    }
    return flow;
}

18、费用流

bool SPFA(){
    Q.push(S);
    memset(vis, 0, sizeof(vis));
    memset(dis, 127, sizeof(dis));
    memset(last, 255, sizeof(last));
    memset(cnt, 0, sizeof(cnt));
    vis[S] = 1; dis[S] = 0;
    while(!Q.empty()){
        int x = Q.front();
        Q.pop(); vis[x]=0;
        for(int t = idx[x]; t; t = edge[t].nxt){
            E& e = edge[t];
            if(e.cap <= e.flow) continue;
            if(dis[e.to] > dis[x] + e.cost){
                last[e.to] = x;
                edges[e.to] = t;
                dis[e.to] = dis[x] + e.cost;
                if(!vis[e.to]) {
                    vis[e.to] = 1;
                    Q.push(e.to);
                }
            }
        }
    }
    return (dis[T] != dis[0]);
}
void mcmf(){
    int flow = 0; int cost = 0;
    while(SPFA()){
        //printf("%d\n", flow);
        int u = T, f = INF;
        while(last[u] != -1){
            f = min(edge[edges[u]].cap - edge[edges[u]].flow, f);
            u = last[u];
        }
        u = T;
        while(last[u] != -1){
            edge[edges[u]].flow += f;
            edge[edges[u] ^ 1].flow -= f;
            u = last[u];
        }
//      printf("***%d",f);
        flow += f;
        cost += dis[T] * f;

    }
    printf("%d\n", cost);
}

19、tarjan

void tarjan(int x){
    dfn[x] = low[x] = ++Time;
    S.push(x); ins[x] = 1;
    for(int t = idx[x] ; t; t = edge[t].nxt){
        E e = edge[t];
        if(!dfn[e.to]){
            tarjan(e.to);
            low[x] = min(low[x], low[e.to]);
        }
        else if(ins[e.to])
            low[x] = min(low[x], dfn[e.to]);
    }
    int now;
    if(dfn[x] == low[x]){
        cnt++;
        do{
            now = S.top();
            S.pop();
            ins[now] = 0;
            col[now] = cnt;
        }while(now != x);
    }
}

20、割点割边双联通

void dfs(int x,int fa){
    int child = 0;
    dfn[x] = low[x] = ++Time;
    for(int t = idx[x]; t; t = edge[t].nxt){
        E e = edge[t];
        E ee = (E) {x, e.to};
        if(!dfn[e.to]){
            S.push(ee);
            child++;
            dfs(e.to, x);
            low[x] = min(low[e.to], low[x]);
            if(low[e.to] >= dfn[x]){
                iscut[x] = 1;
                bcc_cnt++; bcc[bcc_cnt].clear();
                for(;;){
                    E now = S.top(); S.pop();
                    if(bccno[now.u] != bcc_cnt) {
                        bcc[bcc_cnt].push_back(now.u);
                        bccno[now.u] = bcc_cnt;
                    }
                    if(bccno[now.v] != bcc_cnt) {
                        bcc[bcc_cnt].push_back(now.v);
                        bccno[now.v] = bcc_cnt;
                    }
                    if(now.u == x && now.v == e.to) break;
                }

            }
            //if(low[e.to] > dfn[x]) 割边

        }
        else if(dfn[e.to] < dfn[x] && e.to != fa) {
            S.push(ee);
            low[x] = min(low[x], dfn[e.to]);
        }
    }
    if(fa == -1 && child == 1) iscut[x] = 0;
}

21、欧拉回路方案

void dfs(int x) {
    a[x] = 1;
    //printf("%d\n", x);
    for(int &t = idx[x]; t; t = edge[t].nxt) {
        E e = edge[t];
        if(!vis[t / 2]) {
            vis[t / 2] = 1;
            dfs(e.to);
            ans.push_back(e.id);
        }
    }
}

22、

struct AC{
    queue  q;
    int ch[N][27];
    int f[N], last[N], cnt[N];
    int ans;
    int idx(char c){return c - 'a' + 1;}
    int size, now;
    void init() {
        memset(f, 0, sizeof(f));
        memset(last, 0, sizeof(last));
        memset(cnt, 0, sizeof(cnt));
        ans = 0; size = 0;
        memset(ch, 0, sizeof(ch));
    }
    void insert(char* ss){
        now = 0;
        for(int i=0; ss[i]; i++){
            if(!ch[now][idx(ss[i])])
                ch[now][idx(ss[i])] = ++size;
            now = ch[now][idx(ss[i])];
        }
        cnt[now]++;
    }
    void getfail(){
        for(int i = 1; i <= 26; i++)
            if(ch[0][i]) q.push(ch[0][i]);
        while(!q.empty()){
            int r = q.front(); q.pop();
            for(int i = 1;i <= 26; i++){
                int u = ch[r][i];
                if(!u) {ch[r][i] = ch[f[r]][i]; continue;}
                q.push(u);
                int v = f[r];
                while(v && !ch[v][i]) v = f[v];
                f[u] = ch[v][i];
                last[u] = cnt[f[u]] ? f[u] : last[f[u]];
            }
        }
    }
    void calc(int x){
        if(x == 0) return;
        ans += cnt[x];
        cnt[x] = 0;
        calc(last[x]);
    }
    void find(char *s){
        int j=0;
        for(int i = 0; s[i]; i++){
            int c = idx(s[i]);
            j = ch[j][c];
            if(cnt[j]) calc(j);
            else calc(last[j]);
        }
    }
};

23、计算几何

int sgn (double x) {
    if(fabs(x) < eps) return 0;
    return x < 0 ? -1 : 1;
}
double dist (double x, double y) {
    return sqrt(x *x + y * y);
}
struct Point {
    double x, y;
    Point(){}
    Point(double _x, double _y) {
        x = _x; y = _y;
    }
    void input() {
        scanf("%lf%lf", &x, &y);
    }
    void output() {
        printf("%lf %lf\n", x, y);
    }
    bool operator == (const Point &b) {
        return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;
    }
    bool operator < (const Point &b) {
        return sgn(y - b.y) == 0 ? sgn(x - b.x) < 0 : sgn(y - b.y) < 0;
    }
    Point operator + (const Point &b) {
        return Point(x + b.x, y + b.y);
    }
    Point operator - (const Point &b) {
        return Point(x - b.x, y - b.y);
    }
    double operator ^ (const Point &b) {
        return x * b.y - y * b.x;
    }
    double operator * (const Point &b) {
        return x * b.x + y * b.y;
    }
    double dis (const Point &b) {
        return dist(x - b.x, y - b.y);
    }
}p;
struct Line {
    Point s, e;
    Line(){}
    Line(Point _s, Point _e) {
        s = _s; e = _e;
    }
    void input() {
        s.input(); e.input();
    }
    void output() {
        puts("line:");
        s.output(); e.output();
    }
    // 1 left 2 right 3 on
    int relation (Point p) {
        int c = sgn((p - s) ^ (e - s));
        //printf("c : %d\n", c);
        if(c < 0) return 1;
        if(c > 0) return 2;
        return 3;
    }
    void adjust() {
        if(e < s) swap(e, s);
    }
    bool operator < (const Line &b) {
        return s < b.s || (s == b.s && e < b.e);
    }
}line[N], l;

24、2-sat

bool dfs(int x) {
    if(mark[x ^ 1]) return 0;
    if(mark[x]) return 1;
    mark[x] = 1;
    s[++c] = x;
    for(int t = idx[x]; t; t = edge[t].nxt)
        if(!dfs(edge[t].to)) return 0;
    return 1;
}
bool solve() {
    if (!dfs(1)) return false;
    for(int i = 2; i <= 2 * n - 1; i += 2) {
        if(!mark[i] && !mark[i + 1]) {
            c = 0;
            if(!dfs(i)) {
                for(int j = 1; j <= c; j++)
                    mark[s[j]] = 0;
                c = 0;
                if(!dfs(i + 1)) return 0;
            }
        }
    }
    return 1;
}

25、后缀数组

//后缀数组倍增算法,假设输入的字符串为s[1..n]
//sa[i]表示字典序第i小的后缀在串s中的位置
//Rank[i]表示从位置i开始的后缀在串s的所有后缀中排第几
//height[i]表示字典序第i-1小的后缀与字典序第i小的后缀的最长公共前缀
void buildsa(int m){
    int i,*x=t1,*y=t2;
    for(i = 1; i <= m; i++) c[i] = 0;
    for(i = 1; i <= n; i++) c[x[i] = s[i]]++;
    for(i = 1; i <= m; i++) c[i] += c[i - 1];
    for(i = n; i >= 1; i--) sa[c[x[i]]--] = i;
    for(int k = 1; k <= n;k <<= 1){
        int p = 0;
        for(i = n - k + 1; i <= n; i++) y[++p] = i;
        for(i = 1; i <= n; i++) if(sa[i] > k) y[++p] = sa[i] - k;
        for(i = 1; i <= m; i++) c[i] = 0;
        for(i = 1; i <= n; i++) c[x[y[i]]]++;
        for(i = 1; i <= m; i++) c[i] += c[i - 1];
        for(i = n; i >= 1; i--) sa[c[x[y[i]]]--] = y[i];
        swap(x, y); p = 1; x[sa[1]] = 1;
        for(i = 2; i <= n; i++)
            x[sa[i]] = (y[sa[i]] == y[sa[i - 1]]
             && y[sa[i] + k] == y[sa[i - 1] + k]) ?
             p : ++p;
        if(p >= n) break;
        m = p;
    }
}
void getheight(){
    int i, j, k = 0;
    for(i = 1; i <= n; i++) Rank[sa[i]] = i;
    for(i = 1; i <= n; i++){
        if(k) k--;
        j=sa[Rank[i] - 1]; // sa[rank[i]]=i;
        while(s[j+k] == s[i+k]) k++;
        height[Rank[i]] = k;
    }
}
26、树链剖分
#include
#include
#include
#include
using namespace std;
const int M=200010;
const int inf=0x7fffffff;
struct E {int to,nxt;}edge[M*2];
struct SEG {int l,r,sum,mx;}tree[M*2];
int v[M],fa[M],size[M],son[M],dep[M],top[M],w[M],f[M];
int n,q,tot=1,idx[M],vis[M],cnt,retsum,retmax;
void addedge(int from,int to){
    edge[tot].to=to;edge[tot].nxt=idx[from];idx[from]=tot++;
}
void init(){
    scanf("%d",&n);
    for(int i=1;i>1;
    build_seg(k<<1,a,mid);build_seg(k<<1|1,mid+1,b);
    tree[k].mx=max(tree[k<<1].mx,tree[k<<1|1].mx);
    tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
}
void change(int k,int a,int x){
    if(atree[k].r) return;
    if(a==tree[k].l && a==tree[k].r)
        {tree[k].mx=x,tree[k].sum=x;return;}
    change(k<<1,a,x);change(k<<1|1,a,x);
    tree[k].mx=max(tree[k<<1].mx,tree[k<<1|1].mx);
    tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
}
int getsum(int k,int a,int b){
    if(btree[k].r) return 0;
    if(a<=tree[k].l && tree[k].r<=b) return tree[k].sum;
    return getsum(k<<1,a,b)+getsum(k<<1|1,a,b);
}
int getmax(int k,int a,int b){
    if(btree[k].r) return -inf;
    if(a<=tree[k].l && tree[k].r<=b) return tree[k].mx;
    return max(getmax(k<<1,a,b),getmax(k<<1|1,a,b));
}
void solve(int x,int y,int opt){
    int f1=top[x],f2=top[y];
    retmax=-inf,retsum=0;
    while(f1!=f2){
        if(dep[f1]
27、莫队算法
所以有一个比较优雅的替代品。那就是先对序列分块。然后对于所有询问按照L所在块的大小
排序。如果一样再按照R排序。然后按照排序后的顺序计算。为什么这样计算就可以降低复杂度呢。
一、i与i+1在同一块内,r单调递增,所以r是O(n)的。由于有n^0.5块,所以这一部
分时间复杂度是n^1.5。
二、i与i+1跨越一块,r最多变化n,由于有n^0.5块,所以这一部分时间复杂度是n^1.5
三、i与i+1在同一块内时变化不超过n^0.5,跨越一块也不会超过2*n^0.5,不
妨看作是n^0.5。由于有n个数,所以时间复杂度是n^1.5
于是就变成了O(n^1.5)了。
而我们知道 莫队算法的O(n^1.5)是基于O(1)得到[l-1,r]结果的
然而这道题 查逆序对 需要O(logn)时间用树状数组完成= =
所以复杂度O(n^1.5*logn)。。
#include
#include
#include
#include
#define lowbit(pos) pos&(-pos)
using namespace std;
const int M=50010;
int a[M],disc[M],bl[M],c[M];
int N,Q;
struct qu {int l,r,id,ans;}q[M];
bool cmp(qu x,qu y){
    if(bl[x.l]==bl[y.l]) return x.rr) {r++;add(a[r],1);now+=r-l+1-query(a[r]);}
        while(q[i].l>l) {add(a[l],-1);now-=query(a[l]-1);l++;}
        while(q[i].r
28、点分治
#include 
#include 
#include 
using namespace std;
const int inf = 0x7fffffff;
const int N = 10005;
int n, tot, idx[N], root, ans, sum, sz[N], f[N], d[N], dep[N], p, K;
bool can[N];
struct E {int to, nxt, w;}edge[N * 2];

void init() {
    memset(idx, 0, sizeof(idx));
    tot = 1;
    memset(can, 0, sizeof(can));
    sum = n; ans = 0; root = 0; f[root] = inf;
    for(int i = 0; i < N; i++) can[i] = 1;
}
void addedge(int from, int to, int w) {
    edge[++tot].to = to; edge[tot].nxt = idx[from]; idx[from] = tot; edge[tot].w = w;
}
void getroot(int x, int fa) {
    sz[x] = 1; f[x] = 0;
    for(int t = idx[x]; t; t = edge[t].nxt) {
        E e = edge[t];
        if(e.to == fa || !can[e.to]) continue;
        getroot(e.to, x);
        sz[x] += sz[e.to];
        f[x] = max(sz[e.to], f[x]);
    }
    sz[x]++;
    f[x] = max(sum - sz[x], f[x]);
    if(f[x] < f[root]) root = x;
}
void getdeep(int x, int fa) {
    d[++p] = dep[x];
    for(int t = idx[x]; t; t = edge[t].nxt) {
        E e = edge[t];
        if(e.to == fa || can[e.to] == 0) continue;
        dep[e.to] = dep[x] + e.w;
        getdeep(e.to, x);
    }
}
int calc(int x, int now) {
    int ret = 0;
    dep[x] = now; p = 0;
    getdeep(x, -1); //printf("%d : ", x);
    //for(int i = 1; i <= p; i++) printf("%d ", d[i]); puts("");
    sort(d + 1, d + 1 + p);
    int l = 1, r = p;
    for(int l = 1; l <= p; l++) {
        while(d[l] + d[r] > K && l < r) r--;
        if(l >= r) break;
        ret += (r - l);
    }
    return ret;
}
void work(int x) {
    ans += calc(x, 0);
    //printf("%d %d\n", can[3], can[4]);
    can[x] = 0;
    for(int t = idx[x]; t; t = edge[t].nxt) {
        E e = edge[t];
        if(!can[e.to]) continue;
        //printf("%d\n", e.to);
        ans -= calc(e.to, e.w);
        sum = sz[e.to];
        root = 0;
        getroot(e.to, -1); //printf("%d %d\n", e.to, root); return;
        work(root);
    }
}
int main() {
    while(scanf("%d%d", &n, &K) && n + K) {
        init();
        for(int i = 1, x, y, z; i < n; i++)
            scanf("%d%d%d", &x, &y, &z),
            addedge(x, y, z), addedge(y, x, z);
        getroot(1, -1);
        work(root);
        printf("%d\n", ans);
    }
    return 0;
}
29、二维rmq
int getmax(int X1, int Y1, int X2, int Y2) {
    int k1 = LOG[X2 - X1 + 1];
    int k2 = LOG[Y2 - Y1 + 1];
    X2 = X2 - (1 << k1) + 1;
    Y2 = Y2 - (1 << k2) + 1;
    return max(max(maxx[X1][Y1][k1][k2], maxx[X1][Y2][k1][k2]),
    max(maxx[X2][Y1][k1][k2] ,maxx[X2][Y2][k1][k2]));
}
int getmin(int X1, int Y1, int X2, int Y2) {
    int k1 = LOG[X2 - X1 + 1];
    int k2 = LOG[Y2 - Y1 + 1];
    X2 = X2 - (1 << k1) + 1;
    Y2 = Y2 - (1 << k2) + 1;
    return min(min(minn[X1][Y1][k1][k2], minn[X1][Y2][k1][k2]),
    min(minn[X2][Y1][k1][k2] ,minn[X2][Y2][k1][k2]));
}
int main() {
    scanf("%d%d%d", &n, &b, &k);
    LOG[0] = -1;
    for(int i = 1; i <= 254; i++)
        LOG[i] = ((i & (i - 1)) == 0) ? 
        LOG[i - 1] + 1 : LOG[i - 1];

    for(int i = 1, x; i <= n; i++)
        for(int j = 1; j <= n; j++)
            scanf("%d", &x),
            minn[i][j][0][0] = maxx[i][j][0][0] = x;
    for(int ii = 0; ii <= LOG[n]; ii++)
    for(int jj = 0; jj <= LOG[n]; jj++)
    if(ii + jj)
        for(int i = 1; i + (1 << ii) - 1 <= n; i++)
        for(int j = 1; j + (1 << jj) - 1 <= n; j++)
        if(ii)
        minn[i][j][ii][jj] = min(minn[i][j][ii - 1][jj],
         minn[i + (1 << (ii - 1))][j][ii - 1][jj]),
        maxx[i][j][ii][jj] = max(maxx[i][j][ii - 1][jj],
             maxx[i + (1 << (ii - 1))][j][ii - 1][jj]);
        else
        minn[i][j][ii][jj] = min(minn[i][j][ii][jj - 1],
             minn[i][j + (1 << (jj - 1))][ii][jj - 1]),
        maxx[i][j][ii][jj] = max(maxx[i][j][ii][jj - 1],
             maxx[i][j + (1 << (jj - 1))][ii][jj - 1]);
    for(int i = 1, x, y; i <= k; i++) {
        scanf("%d%d", &x, &y);
        printf("%d\n", getmax(x, y, x + b - 1, y + b - 1) -
        getmin(x, y, x + b - 1, y + b - 1));
    }
    return 0;
}
30、rmq
int getmax(int l, int r) {
    int k = LOG[r - l + 1];
    r = r - (1 << k) + 1;
    return max(maxx[l][k], maxx[r][k]);
}
int getmin(int l, int r) {
    int k = LOG[r - l + 1];
    r = r - (1 << k) + 1;
    return min(minn[l][k], minn[r][k]);
}
int main(){
    LOG[0] = -1;
    for(int i = 1; i < N; i++)
        LOG[i] = ((i & (i - 1)) == 0) ?
         LOG[i - 1] + 1 : LOG[i - 1];
    while(scanf("%d%d", &n, &q) != EOF){
        for(int i = 1; i <= n; i++)
            scanf("%d", &minn[i][0]),
            maxx[i][0] = minn[i][0];
            for(int j = 1; j <= 19; j++)
                for(int i = 1; i <= n; i++){
                int k = i + (1 << j) - 1;
                if(k > n) break;
                minn[i][j] = min(minn[i][j - 1],
                 minn[i + (1 << (j - 1))][j - 1]);
                maxx[i][j] = max(maxx[i][j - 1],
                 maxx[i + (1 << (j - 1))][j - 1]);
            }
        for(int i = 1, l, r; i <= q; i++) {
            scanf("%d%d", &l, &r);
            printf("%d\n", getmax(l, r) -
            getmin(l, r));
        }
    }
    return 0;
}
31、树上rmq
void dfs(int x, int f) {
    vis[x] = 1;
    for(int t = idx[x]; t; t = edge[t].nxt) {
        E e = edge[t];
        if(e.to == f) continue;
        if(vis[e.to]) {
            X = x; Y = e.to; W = e.w; continue;
        }
        dep[e.to] = dep[x] + 1;
        fa[e.to][0] = x;
        w[e.to][0] = e.w;
        for(int k = 1; k <= LOG[dep[e.to]]; k++)
            fa[e.to][k] = fa[fa[e.to][k - 1]][k - 1],
            w[e.to][k] = 
            w[e.to][k - 1] + w[fa[e.to][k - 1]][k - 1];
        dfs(e.to, x);
    }
}
ll query(int x, int y) {
    ll ans = 0;
    int h = dep[y] - dep[x];
    while(h > 0) {
        ans += w[y][LOG[h]];
        y = fa[y][LOG[h]];
        h = dep[y] - dep[x];
    }
    h = dep[x] - dep[y];
    while(h > 0) {
        ans += w[x][LOG[h]];
        x = fa[x][LOG[h]];
        h = dep[x] - dep[y];
    }
    if(x == y) return ans;
    h = dep[y];
    for(int k = LOG[h]; k >= 0; k--)
    if(fa[x][k] != fa[y][k]) {
        ans += w[x][k];
        ans += w[y][k];
        x = fa[x][k];
        y = fa[y][k];
    }
    ans += (w[x][0] + w[y][0]);
    return ans;
}
32、fft
#include
#include
#include
#include
#include
#define N 300000
#define pi acos(-1.0)
using namespace std;
typedef complex cd;
char s1[N],s2[N];
cd f[N],g[N],eps[N],c_eps[N];
int n,m,a[N];
void init(){
    for(int i=0;ij) swap(x[i],x[j]);
        for(int l=n>>1;(j^=l)>=1);
    }
    for(int i=2;i<=n;i<<=1){
        int m=i>>1;
        for(int j=0;j=0;i--) printf("%d",a[i]);
    return 0;
}
33、错排


34、莫队算法:至少存在k次的数
#include
#include
#include
#include
#define N 100005
struct Q{
    int l,r,k,ans,id;
}q[N];
int n,m,a[N],num[N],cnt[N],block[N],tot[N],End[N],Begin[N];
using namespace std;
int read(){
    char ch=getchar();int f=1,x=0;
    while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
bool cmp(Q x,Q y){
    return block[x.l]q[i].r;r--) upd(r,-1);
        for(;l>q[i].l;l--) upd(l-1,1);
        for(;l
35、最小表示法
#include
#include
#include
using namespace std;
int T;
char s[20005];
int MinR(){
    int l=strlen(s+1);
    for(int i=l+1;i<=l+l;i++) s[i]=s[i-l];
    int i=1,j=2,k;
    while(i<=l&&j<=l){
        k=0;
        while(s[i+k]==s[j+k]&&ks[j+k])
            if(i+k+1>j) i=i+k+1;
            else i=j+1;
        else
            if(j+k+1>i) j=j+k+1;
            else j=i+1;
    }
    if(i<=l) return i;
    else return j;
}
int main(){
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    scanf("%d",&T);
    while(T--){
        scanf("%s",s+1);
        printf("%d\n",MinR());
    }
    return 0;
}
36、lucas定理
#include
#include
#include
#define Mo 10007
#define ll long long
using namespace std;
const int N=10010;
ll fac[N];
ll n,m;
void exgcd(ll a,ll b,ll &x,ll &y){
    if(!b){x=1;y=0;return;}
    else{exgcd(b,a%b,y,x);y-=(a/b)*x;}
}
ll inv(ll a){
    ll x,y;
    exgcd(a,10007,x,y);
    return (x%Mo+Mo)%Mo;
}
ll C(ll n,ll m){
    if(m==0) return 1;
    if(n

你可能感兴趣的:(ACM模板)