简单的模板整理(待续)

ACM模板 0.4

鉴于被穿了小鞋,马而克之。 __φ(..;)

你们要的萝莉


1.高精度

1) C++版
#include<iostream> 
#include<string> 
#include<iomanip> 
#include<algorithm> 
using namespace std; 

#define MAXN 9999
#define MAXSIZE 10
#define DLEN 4

class BigNum
{ 
private: 
    int a[500];    //可以控制大数的位数 
    int len;       //大数长度
public: 
    BigNum(){ len = 1;memset(a,0,sizeof(a)); }   //构造函数
    BigNum(const int);       //将一个int类型的变量转化为大数
    BigNum(const char*);     //将一个字符串类型的变量转化为大数
    BigNum(const BigNum &);  //拷贝构造函数
    BigNum &operator=(const BigNum &);   //重载赋值运算符,大数之间进行赋值运算

    friend istream& operator>>(istream&,  BigNum&);   //重载输入运算符
    friend ostream& operator<<(ostream&,  BigNum&);   //重载输出运算符

    BigNum operator+(const BigNum &) const;   //重载加法运算符,两个大数之间的相加运算 
    BigNum operator-(const BigNum &) const;   //重载减法运算符,两个大数之间的相减运算 
    BigNum operator*(const BigNum &) const;   //重载乘法运算符,两个大数之间的相乘运算 
    BigNum operator/(const int   &) const;    //重载除法运算符,大数对一个整数进行相除运算

    BigNum operator^(const int  &) const;    //大数的n次方运算
    int    operator%(const int  &) const;    //大数对一个int类型的变量进行取模运算    
    bool   operator>(const BigNum & T)const;   //大数和另一个大数的大小比较
    bool   operator>(const int & t)const;      //大数和一个int类型的变量的大小比较

    void print();       //输出大数
}; 
BigNum::BigNum(const int b)     //将一个int类型的变量转化为大数
{ 
    int c,d = b;
    len = 0;
    memset(a,0,sizeof(a));
    while(d > MAXN)
    {
        c = d - (d / (MAXN + 1)) * (MAXN + 1); 
        d = d / (MAXN + 1);
        a[len++] = c;
    }
    a[len++] = d;
}
BigNum::BigNum(const char*s)     //将一个字符串类型的变量转化为大数
{
    int t,k,index,l,i;
    memset(a,0,sizeof(a));
    l=strlen(s);   
    len=l/DLEN;
    if(l%DLEN)
        len++;
    index=0;
    for(i=l-1;i>=0;i-=DLEN)
    {
        t=0;
        k=i-DLEN+1;
        if(k<0)
            k=0;
        for(int j=k;j<=i;j++)
            t=t*10+s[j]-'0';
        a[index++]=t;
    }
}
BigNum::BigNum(const BigNum & T) : len(T.len)  //拷贝构造函数
{ 
    int i; 
    memset(a,0,sizeof(a)); 
    for(i = 0 ; i < len ; i++)
        a[i] = T.a[i]; 
} 
BigNum & BigNum::operator=(const BigNum & n)   //重载赋值运算符,大数之间进行赋值运算
{
    int i;
    len = n.len;
    memset(a,0,sizeof(a)); 
    for(i = 0 ; i < len ; i++) 
        a[i] = n.a[i]; 
    return *this; 
}
istream& operator>>(istream & in,  BigNum & b)   //重载输入运算符
{
    char ch[MAXSIZE*4];
    int i = -1;
    in>>ch;
    int l=strlen(ch);
    int count=0,sum=0;
    for(i=l-1;i>=0;)
    {
        sum = 0;
        int t=1;
        for(int j=0;j<4&&i>=0;j++,i--,t*=10)
        {
            sum+=(ch[i]-'0')*t;
        }
        b.a[count]=sum;
        count++;
    }
    b.len =count++;
    return in;

}
ostream& operator<<(ostream& out,  BigNum& b)   //重载输出运算符
{
    int i;  
    cout << b.a[b.len - 1]; 
    for(i = b.len - 2 ; i >= 0 ; i--)
    { 
        cout.width(DLEN); 
        cout.fill('0'); 
        cout << b.a[i]; 
    } 
    return out;
}

BigNum BigNum::operator+(const BigNum & T) const   //两个大数之间的相加运算
{
    BigNum t(*this);
    int i,big;      //位数   
    big = T.len > len ? T.len : len; 
    for(i = 0 ; i < big ; i++) 
    { 
        t.a[i] +=T.a[i]; 
        if(t.a[i] > MAXN) 
        { 
            t.a[i + 1]++; 
            t.a[i] -=MAXN+1; 
        } 
    } 
    if(t.a[big] != 0)
        t.len = big + 1; 
    else
        t.len = big;   
    return t;
}
BigNum BigNum::operator-(const BigNum & T) const   //两个大数之间的相减运算 
{  
    int i,j,big;
    bool flag;
    BigNum t1,t2;
    if(*this>T)
    {
        t1=*this;
        t2=T;
        flag=0;
    }
    else
    {
        t1=T;
        t2=*this;
        flag=1;
    }
    big=t1.len;
    for(i = 0 ; i < big ; i++)
    {
        if(t1.a[i] < t2.a[i])
        { 
            j = i + 1; 
            while(t1.a[j] == 0)
                j++; 
            t1.a[j--]--; 
            while(j > i)
                t1.a[j--] += MAXN;
            t1.a[i] += MAXN + 1 - t2.a[i]; 
        } 
        else
            t1.a[i] -= t2.a[i];
    }
    t1.len = big;
    while(t1.a[len - 1] == 0 && t1.len > 1)
    {
        t1.len--; 
        big--;
    }
    if(flag)
        t1.a[big-1]=0-t1.a[big-1];
    return t1; 
} 

BigNum BigNum::operator*(const BigNum & T) const   //两个大数之间的相乘运算 
{ 
    BigNum ret; 
    int i,j,up; 
    int temp,temp1;   
    for(i = 0 ; i < len ; i++)
    { 
        up = 0; 
        for(j = 0 ; j < T.len ; j++)
        { 
            temp = a[i] * T.a[j] + ret.a[i + j] + up; 
            if(temp > MAXN)
            { 
                temp1 = temp - temp / (MAXN + 1) * (MAXN + 1); 
                up = temp / (MAXN + 1); 
                ret.a[i + j] = temp1; 
            } 
            else
            { 
                up = 0; 
                ret.a[i + j] = temp; 
            } 
        } 
        if(up != 0) 
            ret.a[i + j] = up; 
    } 
    ret.len = i + j; 
    while(ret.a[ret.len - 1] == 0 && ret.len > 1)
        ret.len--; 
    return ret; 
} 
BigNum BigNum::operator/(const int & b) const   //大数对一个整数进行相除运算
{ 
    BigNum ret; 
    int i,down = 0;   
    for(i = len - 1 ; i >= 0 ; i--)
    { 
        ret.a[i] = (a[i] + down * (MAXN + 1)) / b; 
        down = a[i] + down * (MAXN + 1) - ret.a[i] * b; 
    } 
    ret.len = len; 
    while(ret.a[ret.len - 1] == 0 && ret.len > 1)
        ret.len--; 
    return ret; 
}
int BigNum::operator %(const int & b) const    //大数对一个int类型的变量进行取模运算    
{
    int i,d=0;
    for (i = len-1; i>=0; i--)
    {
        d = ((d * (MAXN+1))% b + a[i])% b;  
    }
    return d;
}
BigNum BigNum::operator^(const int & n) const    //大数的n次方运算
{
    BigNum t,ret(1);
    int i;
    if(n<0)
        exit(-1);
    if(n==0)
        return 1;
    if(n==1)
        return *this;
    int m=n;
    while(m>1)
    {
        t=*this;
        for( i=1;i<<1<=m;i<<=1)
        {
            t=t*t;
        }
        m-=i;
        ret=ret*t;
        if(m==1)
            ret=ret*(*this);
    }
    return ret;
}
bool BigNum::operator>(const BigNum & T) const   //大数和另一个大数的大小比较
{ 
    int ln; 
    if(len > T.len)
        return true; 
    else if(len == T.len)
    { 
        ln = len - 1; 
        while(a[ln] == T.a[ln] && ln >= 0)
            ln--; 
        if(ln >= 0 && a[ln] > T.a[ln])
            return true; 
        else
            return false; 
    } 
    else
        return false; 
}
bool BigNum::operator >(const int & t) const    //大数和一个int类型的变量的大小比较
{
    BigNum b(t);
    return *this>b;
}

void BigNum::print()    //输出大数
{ 
    int i;   
    cout << a[len - 1]; 
    for(i = len - 2 ; i >= 0 ; i--)
    { 
        cout.width(DLEN); 
        cout.fill('0'); 
        cout << a[i]; 
    } 
    cout << endl;
}
int main()
{
    int i,n;
    BigNum x[101];      //定义大数的对象数组
    x[0]=1;
    for(i=1;i<101;i++)
        x[i]=x[i-1]*(4*i-2)/(i+1);
    while(scanf("%d",&n)==1 && n!=-1)
    {
        x[n].print();
    }
}
2)java版

BigInteger类:
abs() 返回其值是此BigInteger的绝对值的BigInteger。
compareTo(BigInteger val) 将此BigInteger与指定的BigInteger进行比较。
divide(BigInteger val) 返回其值为 (this / val) 的BigInteger。
pow(int exponent) 返回其值为 (thisexponent) 的BigInteger。
multiply(BigInteger val) 返回其值为 (this * val) 的BigInteger。
gcd(BigInteger val) 返回一个 BigInteger,其值是 abs(this) 和 abs(val) 的最大公约数。
subtract(BigInteger val) 返回其值为 (this - val) 的 BigInteger。
BigDecimal类:
BigDecimal(String val)
将 BigDecimal 的字符串表示形式转换为 BigDecimal。
abs()
返回 BigDecimal,其值为此 BigDecimal 的绝对值,其标度为 this.scale()。
add(BigDecimal augend)
返回一个 BigDecimal,其值为 (this + augend),其标度为 max(this.scale(), augend.scale())。
compareTo(BigDecimal val)
将此 BigDecimal 与指定的 BigDecimal 比较。
divide(BigDecimal divisor, int scale, int roundingMode)
返回一个 BigDecimal,其值为 (this / divisor),其标度为指定标度。
RoundingMode
CEILING
向正无限大方向舍入的舍入模式。
DOWN
向零方向舍入的舍入模式。
FLOOR
向负无限大方向舍入的舍入模式。
HALF_DOWN
向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入。
HALF_EVEN
向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。
HALF_UP
向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入。
UNNECESSARY
用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。
UP
远离零方向舍入的舍入模式。
setScale(int newScale, RoundingMode roundingMode)
返回 BigDecimal,其标度为指定值,其非标度值通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定,以维护其总值。
subtract(BigDecimal subtrahend)
返回一个 BigDecimal,其值为 (this - subtrahend),其标度为 max(this.scale(), subtrahend.scale())。
divide(BigDecimal divisor, RoundingMode roundingMode)
返回一个 BigDecimal,其值为 (this / divisor),其标度为 this.scale()。
更多的函数请参考javaAPI文档

示例:
import java.util.*;
import java.math.*;

public class Main{
    public static void main(String[] args) {
        Scanner cin = new Scanner (System.in);
        int cc = cin.nextInt();
        int cas = 1;
        for (int i=0;i<cc;i++){
            BigInteger a = cin.nextBigInteger();
            BigInteger b = cin.nextBigInteger();
            BigInteger c = a .add( b );
            System.out.println("Case " + cas +":");
            cas++;
            System.out.print(a+" + " + b +" = ");
            System.out.println(c);
            if (i<cc-1)
                System.out.println();
        }
    }
}
3)python版(待续)
gmpy

2.Trie

#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <math.h>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
const int N = 32000005;
const int M = 1000005;
const int INF = 0x3f3f3f3f;
int n,m,k;
LL a;
struct Trie
{
    LL v;
    int nxt[3];
    void init(){
        v=-1;
        memset(nxt,-1,sizeof(nxt));
    }
};

Trie trie[N];
int sz;

LL ans;
LL l,r;

void ini()
{
    sz=1;
    trie[0].init();
}

void insert(LL x,LL ip)
{
    int pos=0;
    for (int i=32;i>=0;i--) 
    {
        int c;
        c = (x&(1LL<<i)) ? 1 : 0;
        if (trie[pos].nxt[c]==-1)
        {
            trie[pos].nxt[c]=sz;
            trie[sz++].init();
        }
        pos=trie[pos].nxt[c];
    }
    trie[pos].v=ip;
}

void query(LL x,LL ip)
{
    int pos=0;
    LL res=0;
    for (int i=32;i>=0;i--)
    {
        int c = (x&(1LL<<i)) ? 1 : 0;
        if (trie[pos].nxt[c^1]!=-1)
        {
            pos=trie[pos].nxt[c^1];
            res=(res|1)<<1;
        }
        else
        {
            pos=trie[pos].nxt[c];
            res=(res|0)<<1;
        }
    }
    res>>=1;
    if (ans<=res)
    {
        if (ans==res)
        {
            if (min(ip,trie[pos].v)+1<l)
            {
                l=min(ip,trie[pos].v)+1;
                r=max(ip,trie[pos].v);
            }
        }
        else
        {
            ans=res;
            l=min(ip,trie[pos].v)+1;
            r=max(ip,trie[pos].v);
        }
    }
}


LL s[N];
int main()
{
    int cc;
    int cas=1;
    scanf("%d",&cc);
    while (cc--)
    {
        ans=0;
        l=INF,r=0;
        ini();
        scanf("%d",&n);
        s[0]=0;
        for (int i=1;i<=n;i++)
        {
            scanf("%lld",&a);
            s[i]=s[i-1]^a;
            insert(s[i],i);
            if (ans<s[i])
            {
                l=1;
                r=i;
                ans=s[i];
            }
        }
        printf("Case #%d:\n", cas++);
        for (int i=1;i<=n;i++)
            query(s[i],i);
        printf("%lld %lld\n", l,r);
    }
    return 0;
}

3.AC自动机

/*
 AC + 高斯消元
 骰子串匹配概率
*/
#include <iostream>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <cstdio>
#include <iomanip>
#include <queue>
#include <map>
using namespace std;
typedef long long LL;
const int N = 557;
const double eps = 0.0001;

int n,m, cc;
int s[N][10], d[N];
double p[N][N];
int ans[N];
struct trie
{
    int sz,val[N],fail[N],tr[N][10];
    void ini()
    {
        sz=0;
        memset(tr,0,sizeof(tr));
        memset(val,0,sizeof(val));
        memset(fail,0,sizeof(fail));
    }
    int insert(int *ch)
    {
        int w=0;
        while (*ch!=-1&&tr[w][*ch])
            w=tr[w][*ch],ch++;
        while (*ch!=-1)
            tr[w][*ch]=++sz,ch++,w=sz;
        val[w]=1;
        return w;
    }
    void bulid()
    {
        queue <int> q;
        for (int i=0;i<6;i++)
            if (tr[0][i])
                q.push(tr[0][i]);
        while (!q.empty())
        {
            int now=q.front();
            q.pop();
            if (val[now])
                continue;
            for (int i=0;i<6;i++)
            {
                if (tr[now][i])
                {
                    fail[tr[now][i]]=tr[fail[now]][i];
                    q.push(tr[now][i]);
                }
                else 
                    tr[now][i]=tr[fail[now]][i];
            }
        }
    }
}AC;
void gauss(int n)
{
    int mi;
    double h;
    for (int i=1;i<=n;i++)
    {
        mi=i;
        for (int j=i;j<=n;j++)
            if (fabs(p[j][i])>fabs(p[mi][j]))
                mi=j;
        if (fabs(p[mi][i])<eps)
            return ;
        if (mi!=i)
            for (int j=i;j<=n+1;j++) 
                swap(p[i][j],p[mi][j]);
        h=p[i][i];
        for (int j=i;j<=n+1;j++)
            p[i][j]/=h;
        for (int j=1;j<=n;j++)
            if (j!=i)
            {
                h-=p[j][i]/p[i][i];
                for (int k=1;k<=n+1;k++)
                    p[j][k]+=h*p[i][k];
            }
    }
}
int main()
{
    int cas=1;
    scanf("%d",&cc);
    while (cc--)
    {
        scanf("%d%d",&n,&m);
        AC.ini();
        for (int i=0;i<n;i++)
        {
            for (int j=0;j<m;j++)
                scanf("%d",&d[j]),d[j]--;
            d[m]=-1;
            ans[i]=AC.insert(d);
        }
        AC.bulid();
        // for (int i=0;i<AC.sz;i++)
        // {
        //     for (int j=0;j<6;j++)
        //         cout<<AC.tr[i][j]<<" ";
        //     cout<<endl;
        // }

        for (int i=0;i<AC.sz;i++)
        {
            d[i]=0;
            for (int j=0;j<6;j++)
                if (AC.tr[i][j])
                    d[i]++;
        }
        memset(p,0,sizeof(p));
        for (int i=1;i<=AC.sz;i++)
            p[i][i]+=1.0;
        for (int i=0;i<6;i++)
            if (AC.tr[0][i])
                p[AC.tr[0][i]][AC.sz+1]+=1.0/d[0];
        for (int i=1;i<AC.sz;i++)
        {
            for (int j=0;j<6;j++)
                if (AC.tr[i][j])
                    p[AC.tr[i][j]][i]-=1.0/6.0;
            if (d[i]!=6&&AC.val[i])
            {
                for (int j=0;j<6;j++)
                    if (AC.tr[0][j])
                        p[AC.tr[0][j]][i]-=1.0*(6-d[i])/(6.0*d[0]);
            }
        }

        gauss(AC.sz);
        for (int i=1;i<n;i++)
            printf("%.6f\n",p[ans[i]][AC.sz+1]);
        printf("%.6f\n",p[ans[n]][AC.sz+1]);
    }
    return 0;
}

4.KD_tree

/*
 最近点距离
*/
#include <cstdio>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long LL;
const int N = 1000007;
const int M = 100005;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
int n,m;
int root;
int ans;
int now;
int ql,qr;
struct nd
{
    int ma[2],mi[2];
    int d[2];
    int l,r;
}t[N<<1];
inline int getint()
{
       int w=0,q=0;
       char c=getchar();
       while((c<'0' || c>'9') && c!='-') c=getchar();
       if (c=='-')  q=1, c=getchar();
       while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
       return q ? -w : w;
}

bool cmp(nd a,nd b)
{
    if (a.d[now] == b.d[now])
        return a.d[!now]<b.d[!now];
    return a.d[now]<b.d[now];
}
void kd_update(int k)
{
    if (t[k].l)
    {
        if (t[t[k].l].ma[0] > t[k].ma[0]) t[k].ma[0]=t[t[k].l].ma[0];
        if (t[t[k].l].ma[1] > t[k].ma[1]) t[k].ma[1]=t[t[k].l].ma[1];
        if (t[t[k].l].mi[0] < t[k].mi[0]) t[k].mi[0]=t[t[k].l].mi[0];
        if (t[t[k].l].mi[1] < t[k].mi[1]) t[k].mi[1]=t[t[k].l].mi[1];
    }
    if (t[k].r)
    {
        if (t[t[k].r].ma[0] > t[k].ma[0]) t[k].ma[0]=t[t[k].r].ma[0];
        if (t[t[k].r].ma[1] > t[k].ma[1]) t[k].ma[1]=t[t[k].r].ma[1];
        if (t[t[k].r].mi[0] < t[k].mi[0]) t[k].mi[0]=t[t[k].r].mi[0];
        if (t[t[k].r].mi[1] < t[k].mi[1]) t[k].mi[1]=t[t[k].r].mi[1];
    }
}
int kd_build(int l,int r,int k)
{
    int mid=(l+r)>>1;
    now=k;
    nth_element(t+l+1,t+mid+1,t+r+1,cmp);
    if (l!=mid)
        t[mid].l=kd_build(l,mid-1,!k);
    if (r!=mid)
        t[mid].r=kd_build(mid+1,r,!k);
    t[mid].ma[0]=t[mid].mi[0]=t[mid].d[0];
    t[mid].ma[1]=t[mid].mi[1]=t[mid].d[1];
    kd_update(mid);
    return mid;
}
int dis(int k)
{
    int res=0;
    if (ql<t[k].mi[0]) res+=t[k].mi[0]-ql;
    if (ql>t[k].ma[0]) res+=ql-t[k].ma[0];
    if (qr<t[k].mi[1]) res+=t[k].mi[1]-qr;
    if (qr>t[k].ma[1]) res+=qr-t[k].ma[1];
    return res;
}
void kd_query(int k)
{
    int dl,dr,d0;
    d0=abs(t[k].d[0]-ql)+abs(t[k].d[1]-qr);
    if (d0<ans)
        ans=d0;
    if (t[k].l) dl=dis(t[k].l); else dl=INF;
    if (t[k].r) dr=dis(t[k].r); else dr=INF;

    if (dl<dr)
    {
        if (dl<ans)
            kd_query(t[k].l);
        if (dr<ans)
            kd_query(t[k].r);
    }
    else
    {
        if (dr<ans)
            kd_query(t[k].r);
        if (dl<ans)
            kd_query(t[k].l);
    }
}
void kd_insert(int k)
{
    int p=root,D=0;
    while (1)
    {
        if (t[k].ma[0]>t[p].ma[0]) t[p].ma[0]=t[k].ma[0];
        if (t[k].ma[1]>t[p].ma[1]) t[p].ma[1]=t[k].ma[1];
        if (t[k].mi[0]<t[p].mi[0]) t[p].mi[0]=t[k].mi[0];
        if (t[k].mi[1]<t[p].mi[1]) t[p].mi[1]=t[k].mi[1];

        if (t[k].d[D]>=t[p].d[D])
        {
            if (!t[p].r)
            {
                t[p].r=k;
                return;
            }
            else
                p=t[p].r;
        }
        else
        {
            if (!t[p].l)
            {
                t[p].l=k;
                return;
            }
            else
                p=t[p].l;
        }
        D=!D;
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    {
        for (int i=1;i<=n;i++)
            scanf("%d%d",&t[i].d[0],&t[i].d[1]);
        root=kd_build(1,n,0);
        int x,y,z;
        for (int i=0;i<m;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            if (x==1)
            {
                n++;
                t[n].ma[0]=y;
                t[n].mi[0]=y;
                t[n].d[0]=y;

                t[n].ma[1]=z;
                t[n].mi[1]=z;
                t[n].d[1]=z;
                kd_insert(n);
            }
            else
            {
                ans=INF;
                ql=y;
                qr=z;
                kd_query(root);
                printf("%d\n", ans);
            }
        }
    }
    return 0;
}

5.KMP

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <math.h>
#include <vector>
#include <string.h>
#include <iomanip>
#include <set>
#include <string>
#include <map>
#include <queue>
using namespace std;
typedef long long LL;
const int N = 1000020 ;
const int MOD = 998244353 ;
const int INF = 0x3f3f3f3f;
const double Pi = acos(-1);
int n,m,p,cc;
int s[N],t[N];
int nextt[N];
int main()
{
    scanf("%d",&cc);
    int cas=1;
    while(cc--)
    {
        scanf("%d%d%d",&n,&m,&p);
        for (int i=0;i<n;i++)
            scanf("%d",&s[i]);
        for (int i=0;i<m;i++)
            scanf("%d",&t[i]);
        //Next Array
        nextt[0]=0;
        nextt[1]=0;
        for (int i=1;i<m;i++)
        {
            int j=nextt[i];
            while (j && t[i]!=t[j])
                j=nextt[j];
            nextt[i+1] = t[i] == t[j] ? j+1 : 0 ;
        }
        // Find
        int ans=0;
        int j=0;
        for (int sta=0;sta<p;sta++)
            for (int i=sta,j=0;i<n;i+=p)
            {
                while (j && s[i]!=t[j])
                    j=nextt[j];
                if (s[i]==t[j])
                    j++;
                if (j==m)
                {
                    // printf("bug: %d\n",i-m+1);  // Found!
                    ans++;
                }
            }
        printf("Case #%d: %d\n",cas++,ans);
        memset(nextt,0,sizeof(nextt));
        memset(s,0,sizeof(s));
        memset(t,0,sizeof(t));
    }
    return 0;
}

6.半平面交

//多边形的核
#include <stdio.h>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <math.h>
using namespace std;
const int N = 300005;
const double EXP = 1e-8;
typedef long long LL;
struct point
{
    double x , y ;
}p[N];
struct line
{
    point a,b;
    double angle;
}l[N];
int cas,n,top,bot,order[N],ln,dq[N];
double abs(double a)
{
    if (a<0)
        return -a;
    return a;
}
int dblcmp(double k)
{
    if (abs(k)<EXP)
        return 0;
    return k>0?1:-1;
}
double det(point p0,point p1,point p2)
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
}
bool cmp(int a,int b)
{
    int d = dblcmp(l[a].angle-l[b].angle);
    if (d==0)
        return dblcmp(det(l[a].a,l[b].a,l[b].b))<0;  //  逆时针输入(取左侧)时为">"
    return d<0;
}
void getIntersect (line l1,line l2,point &p)
{
    double d1,d2;
    d1=det(l2.a,l1.b,l1.a);
    d2=det(l1.b,l2.b,l1.a);
    p.x=(l2.a.x*d2+l2.b.x*d1)/(d2+d1);
    p.y=(l2.a.y*d2+l2.b.y*d1)/(d2+d1);
}
bool judge (line l0,line l1,line l2)
{
    point p;
    getIntersect(l1,l2,p);
    return dblcmp(det(p,l0.a,l0.b))>0;      //  逆时针输入(即取左侧)时为"<"
}
void addline(double x1,double y1,double x2,double y2)
{
    l[ln].a.x=x1;
    l[ln].a.y=y1;
    l[ln].b.x=x2;
    l[ln].b.y=y2;
    l[ln].angle=atan2(y2-y1,x2-x1);
    order[ln]=ln;
    ln++;
}
void halfPlaneIntersection()
{
    int i,j;
    sort(order,order+ln,cmp);
    for (i=1,j=0;i<ln;i++)
        if (dblcmp(l[order[i]].angle-l[order[j]].angle)>0)
            order[++j]=order[i];
    ln=j+1;
    dq[0]=order[0];
    dq[1]=order[1];
    bot=0;
    top=1;
    for (i=2;i<ln;i++)
    {
        while (bot<top&&judge(l[order[i]],l[dq[top-1]],l[dq[top]]))
            top--;
        while (bot<top&&judge(l[order[i]],l[dq[bot+1]],l[dq[bot]]))
            bot++;
        dq[++top]=order[i];
    }
    while (bot<top&&judge(l[order[bot]],l[dq[top-1]],l[dq[top]]))
        top--;
    while (bot<top&&judge(l[order[top]],l[dq[bot+1]],l[dq[bot]]))
        bot++;
}
bool isCore()
{
    if (top-bot>1)
        return true;
    return false;
}
int main ()
{
    int i;
    scanf ("%d",&cas);
    while (cas--)
    {
        scanf ("%d",&n);
        for (i=0;i<n;i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        for (ln=i=0;i<n-1;i++)
            addline(p[i].x,p[i].y,p[i+1].x,p[i+1].y);
        addline(p[i].x,p[i].y,p[0].x,p[0].y);
        halfPlaneIntersection();
        if (isCore())
            printf("YES\n");
        else
            printf("NO\n");
    }
return 0 ;
}

7.大素数(论文题,Meisell-Lehmer , 范围~1e11)

//Meisell-Lehmer
//G++ 218ms 43252k
#include<cstdio>
#include<cmath>
using namespace std;
#define LL long long
const int N = 5e6 + 2;
bool np[N];
int prime[N], pi[N];
int getprime()
{
    int cnt = 0;
    np[0] = np[1] = true;
    pi[0] = pi[1] = 0;
    for(int i = 2; i < N; ++i)
    {
        if(!np[i]) prime[++cnt] = i;
        pi[i] = cnt;
        for(int j = 1; j <= cnt && i * prime[j] < N; ++j)
        {
            np[i * prime[j]] = true;
            if(i % prime[j] == 0)   break;
        }
    }
    return cnt;
}
const int M = 7;
const int PM = 2 * 3 * 5 * 7 * 11 * 13 * 17;
int phi[PM + 1][M + 1], sz[M + 1];
void init()
{
    getprime();
    sz[0] = 1;
    for(int i = 0; i <= PM; ++i)  phi[i][0] = i;
    for(int i = 1; i <= M; ++i)
    {
        sz[i] = prime[i] * sz[i - 1];
        for(int j = 1; j <= PM; ++j) phi[j][i] = phi[j][i - 1] - phi[j / prime[i]][i - 1];
    }
}
int sqrt2(LL x)
{
    LL r = (LL)sqrt(x - 0.1);
    while(r * r <= x)   ++r;
    return int(r - 1);
}
int sqrt3(LL x)
{
    LL r = (LL)cbrt(x - 0.1);
    while(r * r * r <= x)   ++r;
    return int(r - 1);
}
LL getphi(LL x, int s)
{
    if(s == 0)  return x;
    if(s <= M)  return phi[x % sz[s]][s] + (x / sz[s]) * phi[sz[s]][s];
    if(x <= prime[s]*prime[s])   return pi[x] - s + 1;
    if(x <= prime[s]*prime[s]*prime[s] && x < N)
    {
        int s2x = pi[sqrt2(x)];
        LL ans = pi[x] - (s2x + s - 2) * (s2x - s + 1) / 2;
        for(int i = s + 1; i <= s2x; ++i) ans += pi[x / prime[i]];
        return ans;
    }
    return getphi(x, s - 1) - getphi(x / prime[s], s - 1);
}
LL getpi(LL x)
{
    if(x < N)   return pi[x];
    LL ans = getphi(x, pi[sqrt3(x)]) + pi[sqrt3(x)] - 1;
    for(int i = pi[sqrt3(x)] + 1, ed = pi[sqrt2(x)]; i <= ed; ++i) ans -= getpi(x / prime[i]) - i + 1;
    return ans;
}
LL lehmer_pi(LL x)
{
    if(x < N)   return pi[x];
    int a = (int)lehmer_pi(sqrt2(sqrt2(x)));
    int b = (int)lehmer_pi(sqrt2(x));
    int c = (int)lehmer_pi(sqrt3(x));
    LL sum = getphi(x, a) +(LL)(b + a - 2) * (b - a + 1) / 2;
    for (int i = a + 1; i <= b; i++)
    {
        LL w = x / prime[i];
        sum -= lehmer_pi(w);
        if (i > c) continue;
        LL lim = lehmer_pi(sqrt2(w));
        for (int j = i; j <= lim; j++) sum -= lehmer_pi(w / prime[j]) - (j - 1);
    }
    return sum;
}
int main()
{
    init();
    LL n;
    while(~scanf("%lld",&n))
    {
        printf("%lld\n",lehmer_pi(n));
    }
    return 0;
}

8.二分图最大匹配(匈牙利算法)

#include<iostream>
#include<cstdio>
#include<vector>
#include<string.h>
using namespace std;
#define M 10005
int n,k,a,b;
int match[M],used[M];
vector <int> G[M];
void add(int a,int b)
{
    G[a].push_back(b);
    G[b].push_back(a);
}
int dfs(int v)
{
    used[v]=1;
    for (int i=0;i<G[v].size();i++)
    {
        int u=G[v][i];
        int w=match[u];
        if (w<0||!used[w]&&dfs(w))
        {
            match[u]=v;
            match[v]=u;
            return 1;
        }
    }
    return 0;
}
int bi_match()
{
    int ans=0;
    memset(match,-1,sizeof(match));
    for (int v=0;v<n;v++)
    {
        memset(used,0,sizeof(used));
        if (dfs(v))
            ans++;
    }
    return ans;
}
int main()
{
    scanf("%d%d",&n,&k);
    int v=n*2;
    for (int i=0;i<k;i++)
    {
        scanf("%d%d",&a,&b);
        add(a-1,n+b-1);
    }
    printf("%d",bi_match());
    return 0;
}

9.费用流

1)基于spfa的MCMF
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <queue>
#define V 10100
#define E 1000100
#define inf 99999999
using namespace std;
int vis[V];
int dist[V];
int pre[V];

struct Edge{
    int u,v,c,cost,next;
}edge[E];
int head[V],cnt;

void init(){
    cnt=0;
    memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int c,int cost)
{
    edge[cnt].u=u;edge[cnt].v=v;edge[cnt].cost=cost;
    edge[cnt].c=c;edge[cnt].next=head[u];head[u]=cnt++;

    edge[cnt].u=v;edge[cnt].v=u;edge[cnt].cost=-cost;
    edge[cnt].c=0;edge[cnt].next=head[v];head[v]=cnt++;
}

bool spfa(int begin,int end){
    int u,v;
    queue<int> q;
    for(int i=0;i<=end+2;i++){
        pre[i]=-1;
        vis[i]=0;
        dist[i]=inf;
    }
    vis[begin]=1;
    dist[begin]=0;
    q.push(begin);
    while(!q.empty()){
        u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];i!=-1;i=edge[i].next){
            if(edge[i].c>0){
                v=edge[i].v;
                if(dist[v]>dist[u]+edge[i].cost){
                    dist[v]=dist[u]+edge[i].cost;
                    pre[v]=i;
                    if(!vis[v]){
                        vis[v]=true;
                        q.push(v);
                    }
                }
            }
        }
    }
    return dist[end]!=inf;
}

int MCMF(int begin,int end){
    int ans=0,flow;
    int flow_sum=0;
    while(spfa(begin,end)){
        flow=inf;
        for(int i=pre[end];i!=-1;i=pre[edge[i].u])
            if(edge[i].c<flow)
                flow=edge[i].c;
        for(int i=pre[end];i!=-1;i=pre[edge[i].u]){
            edge[i].c-=flow;
            edge[i^1].c+=flow;
        }
        ans+=dist[end];
        flow_sum += flow;
    }
    //cout << flow_sum << endl;
    return ans;
}

int main()
{
    //freopen("in.txt","r",stdin);
    int n,m,a,b,c;
    while(scanf("%d%d",&n,&m)!=EOF){
        init();
        addedge(0,1,2,0);
        addedge(n,n+1,2,0);
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&a,&b,&c);
            addedge(a,b,1,c);
            addedge(b,a,1,c);
        }
        printf("%d\n",MCMF(0,n+1));
    }
    return 0;
} 
2)ZKW费用流(适合 稠密图二分图)[效率会近高于之前10倍]
//不资瓷负权
#include <iostream>  
#include <algorithm>  
#include <cstring>  
#include <string>  
#include <cstdio>  
#include <cmath>  
#include <queue>  
#include <map>  
#include <set>  
#define eps 1e-5  
#define MAXN 222  
#define MAXM 55555  
#define INF 1000000007  
using namespace std;  
struct EDGE  
{  
    int cost, cap, v;  
    int next, re;  
}edge[MAXM];  
int head[MAXN], e;  
int vis[MAXN];  
int ans, cost, src, des, n;  
void init()  
{  
    memset(head, -1, sizeof(head));  
    e = 0;  
    ans = cost = 0;  
}  
void add(int u, int v, int cap, int cost)  
{  
    edge[e].v = v;  
    edge[e].cap = cap;  
    edge[e].cost = cost;  
    edge[e].re = e + 1;  
    edge[e].next = head[u];  
    head[u] = e++;  
    edge[e].v = u;  
    edge[e].cap = 0;  
    edge[e].cost = -cost;  
    edge[e].re = e - 1;  
    edge[e].next = head[v];  
    head[v] = e++;  
}  
int aug(int u, int f)  
{  
    if(u == des)  
    {  
        ans += cost * f;  
        return f;  
    }  
    vis[u] = 1;  
    int tmp = f;  
    for(int i = head[u]; i != -1; i = edge[i].next)  
        if(edge[i].cap && !edge[i].cost && !vis[edge[i].v])  
        {  
            int delta = aug(edge[i].v, tmp < edge[i].cap ? tmp : edge[i].cap);  
            edge[i].cap -= delta;  
            edge[edge[i].re].cap += delta;  
            tmp -= delta;  
            if(!tmp) return f;  
        }  
    return f - tmp;  
}  
bool modlabel()  
{  
    int delta = INF;  
    for(int u = 1; u <= n; u++)  
        if(vis[u])  
            for(int i = head[u]; i != -1; i = edge[i].next)  
                if(edge[i].cap && !vis[edge[i].v] && edge[i].cost < delta) delta = edge[i].cost;  
    if(delta == INF) return false;  
    for(int u = 1; u <= n; u++)  
        if(vis[u])  
            for(int i = head[u]; i != -1; i = edge[i].next)  
                edge[i].cost -= delta, edge[edge[i].re].cost += delta;  
    cost += delta;  
    return true;  
}  
void costflow()  
{  
    do  
    {  
        do  
        {  
            memset(vis, 0, sizeof(vis));  
        }while(aug(src, INF));  
    }while(modlabel());  
}  
int nt, m;  
struct point  
{  
    int x, y;  
}p[MAXN], h[MAXN];  
int d[MAXN][MAXN];  
char s[MAXN][MAXN];  
int main()  
{  
    while(scanf("%d%d", &m, &nt) != EOF)  
    {  
        if(m == 0 && nt == 0) break;  
        for(int i = 0; i < m; i++)  
            scanf("%s", s[i]);  
        int hcnt = 0, pcnt = 0;  
        for(int i = 0; i < m; i++)  
            for(int j = 0; j < nt; j++)  
            {  
                if(s[i][j] == 'H')  
                {  
                    hcnt++;  
                    h[hcnt].x = i;  
                    h[hcnt].y = j;  
                }  
                else if(s[i][j] == 'm')  
                {  
                    pcnt++;  
                    p[pcnt].x = i;  
                    p[pcnt].y = j;  
                }  
            }  
        for(int i = 1; i <= pcnt; i++)  
            for(int j = 1; j <= hcnt; j++)  
                d[i][j] = abs(p[i].x - h[j].x) + abs(p[i].y - h[j].y);  
        init();  
        n = hcnt + pcnt + 2;  
        src = hcnt + pcnt + 1;  
        des = n;  
        for(int i = 1; i <= pcnt; i++)  
            for(int j = 1; j <= hcnt; j++)  
                add(i, j + pcnt, 1, d[i][j]);  
        for(int i = 1; i <= pcnt; i++)  
            add(src, i, 1, 0);  
        for(int i = 1; i <= hcnt; i++)  
            add(i + pcnt, des, 1, 0);  
        costflow();  
        printf("%d\n", ans);  
    }  
    return 0;  
}  

10.最大流

1)Dinic
#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <string>
#include <cstdio>
#include <set>
#include <string.h>
#include <vector>
#include <queue>
using namespace std;
typedef long long LL;
const int N = 305;
const int INF = (1<<20);
int n,t,a,b,c,m,k;
int map[N][N],dp[N][N];
struct edge 
{
    int to,cap,rev;
};
vector <edge> G[N];
int level [N],iter[N];
int used[N];

void add(int from,int to,int cap)
{
    G[from].push_back((edge){to,cap,G[to].size()});
    G[to].push_back((edge){from,0,G[from].size()-1});
}
void bfs (int s)
{
    memset(level,-1,sizeof(level));
    queue <int> que;
    level[s]=0;
    que.push(s);
    while (!que.empty())
    {
        int v=que.front();
        que.pop();
        for (int i=0;i<G[v].size();i++)
        {
            edge &e= G[v][i];
            if (e.cap>0&&level[e.to]<0)
            {
                level[e.to]=level[v]+1;
                que.push(e.to);
            }
        }
    }
}
int dfs(int v,int t,int f)
{
    if (v==t)
        return f;
    for (int &i=iter[v];i<G[v].size();i++)
    {
        edge &e=G[v][i];
        if (e.cap>0&&level[v]<level[e.to])
        {
            int d=dfs(e.to,t,min(f,e.cap));
            if (d>0)
            {
                e.cap-=d;
                G[e.to][e.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}
int max_flow(int s,int t)
{
    int flow=0;
    for (;;)
    {
        bfs(s);
        if (level[t]<0)
            return flow;
        memset(iter,0,sizeof(iter));
        int f;
        while ((f=dfs(s,t,INF))>0)
            flow+=f;
    }
}

void ini()
{
    for (int i=0;i<=k+c+2;i++)
        G[i].clear();
}
int main()
{
    scanf("%d%d%d",&k,&c,&m);
    {
        int S=0,T=k+c+2;
        n=k+c;
        for (int i=1;i<=k+c;i++)
            for (int j=1;j<=k+c;j++)
            {
                scanf("%d",&map[i][j]);
                dp[i][j]=map[i][j]==0?INF:map[i][j];
            }
        int mi=(INF),ma=0;
        for (int kk=1;kk<=n;kk++)
            for (int j=1;j<=n;j++)
                for (int i=1;i<=n;i++)
                {
                    dp[i][j]=min(dp[i][j],dp[i][kk]+dp[kk][j]);
                }       
        int l=0,r=200*n,mid;
        while (l<r)
        {
            mid=(l+r)>>1;
            ini();
            for (int i=1;i<=k;i++)
            {
                add(S,i,m);
                for (int j=k+1;j<=c+k;j++)
                    if (dp[i][j]<=mid)
                    {
                        add(i,j,1);
                    }
            }
            for (int j=k+1;j<=c+k;j++)
                add(j,T,1);
            int ans=max_flow(S,T);
            if (ans==c)
                r=mid;
            else
                l=mid+1;
        }
        printf("%d\n",l);
    }
    return 0;
}
2)SAP
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define MAXN 111
#define inf 1<<30

struct Edge{
    int v,cap,next;
}edge[MAXN*MAXN];

int n,m,NE,NV;
int head[MAXN];

void Insert(int u,int v,int cap)
{
    edge[NE].v=v;
    edge[NE].cap=cap;
    edge[NE].next=head[u];
    head[u]=NE++;

    edge[NE].v=u;
    edge[NE].cap=0;
    edge[NE].next=head[v];
    head[v]=NE++;
}

int level[MAXN],gap[MAXN];
void bfs(int vt)
{
    memset(level,-1,sizeof(level));
    memset(gap,0,sizeof(gap));
    level[vt]=0;
    gap[level[vt]]++;
    queue<int>que;
    que.push(vt);
    while(!que.empty()){
        int u=que.front();
        que.pop();
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].v;
            if(level[v]!=-1)continue;
            level[v]=level[u]+1;
            gap[level[v]]++;
            que.push(v);
        }
    }
}

int pre[MAXN],cur[MAXN];
int SAP(int vs,int vt)
{
    bfs(vt);
    memset(pre,-1,sizeof(pre));
    memcpy(cur,head,sizeof(head));
    int maxflow=0,aug=inf;
    int u=pre[vs]=vs;
    gap[0]=NV;
    while(level[vs]<NV){
        bool flag=false;
        for(int &i=cur[u];i!=-1;i=edge[i].next){
            int v=edge[i].v;
            if(edge[i].cap>0&&level[u]==level[v]+1){
                flag=true;
                pre[v]=u;
                u=v;
                aug=min(aug,edge[i].cap);
                if(v==vt){
                    maxflow+=aug;
                    for(u=pre[v];v!=vs;v=u,u=pre[u]){
                        edge[cur[u]].cap-=aug;
                        edge[cur[u]^1].cap+=aug;
                    }
                    aug=inf;
                }
                break;
            }
        }
        if(flag)continue;
        int minlevel=NV;
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].v;
            if(edge[i].cap>0&&level[v]<minlevel){
                minlevel=level[v];
                cur[u]=i;
            }
        }
        if(--gap[level[u]]==0)break;
        level[u]=minlevel+1;
        gap[level[u]]++;
        u=pre[u];
    }
    return maxflow;
}

bool map[MAXN][MAXN];
void Build()
{
    NE=0;
    memset(head,-1,sizeof(head));
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(i==j)
                Insert(i,i+n,1);
            else if(map[i][j])
                Insert(i+n,j,inf);
        }
    }
}

int main()
{
 //   freopen("1.txt","r",stdin);
    int u,v,ans;
    while(~scanf("%d%d",&n,&m)){
        NV=2*n;
        memset(map,false,sizeof(map));
        while(m--){
            scanf(" (%d,%d)",&u,&v);
            map[u][v]=map[v][u]=true;

        }
        ans=n;
        for(int vs=0;vs<n;vs++){
            for(int vt=vs+1;vt<n;vt++){
                Build();
                int tp=SAP(vs+n,vt);
                //cout<<"bug: "<<tp<<endl;
                ans=min(ans,tp);
            }
        }
        //if(ans>=n)ans=n;
        printf("%d\n",ans);
    }
    return 0;
}

11.后缀数组

1)倍增法
//包含c的不重复子串个数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int MAXN=100010;
int sa[MAXN];
int t1[MAXN],t2[MAXN],c[MAXN];
int Rank[MAXN],height[MAXN];
/*
       sa[1~~n]为有效值  sa[i]=a则代表排在第 i 位的是第a个后缀。  a属于[0~~n-1]
       rank[0~~n-1]是有效值  rank[i]=b则代表第 i 个后缀排在第b位   b属于[1~~n]
       height[2~~n]是有效值  height[i]=c 则代表排在第 i 位的后缀和排在第i-1的后缀的最长前缀长度是c。
*/
void construct_sa(int s[],int n,int m){
    int i,j,p,*x=t1,*y=t2;
    for(i=0;i<m;i++)c[i]=0;
    for(i=0;i<n;i++)c[x[i]=s[i]]++;
    for(i=1;i<m;i++)c[i]+=c[i-1];
    for(i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
    for(j=1;j<=n;j<<=1){
        p=0;
        for(i=n-j;i<n;i++)y[p++]=i;
        for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;
        for(i=0;i<m;i++)c[i]=0;
        for(i=0;i<n;i++)c[x[y[i]]]++;
        for(i=1;i<m;i++)c[i]+=c[i-1];
        for(i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
        swap(x,y);
        p=1;x[sa[0]]=0;
        for(i=1;i<n;i++)
            x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++;
        if(p>=n)break;
        m=p;
    }
}
void construct_lcp(int s[],int n){
    int k=0;
    for(int i=0;i<=n;i++) Rank[sa[i]]=i;
    for(int i=0;i<n;i++){
        if(k)k--;
        int j=sa[Rank[i]-1];
        while(s[i+k]==s[j+k])k++;
        height[Rank[i]]=k;
    }
}
int fvis[MAXN],pr[MAXN],s[MAXN];
char str[MAXN];
int main(){
    int T,cas=1;
    char ch[10];
    scanf("%d",&T);
    while(T--){
        scanf("%s",ch);
        scanf("%s",str);
        int n=strlen(str),flag=0,fpr;
        for(int i=0;i<=n;i++) s[i]=str[i];
        memset(fvis,0,sizeof(fvis));
        memset(pr,0,sizeof(pr));
        for(int i=n-1;i>=0;i--){
            if(str[i]==ch[0]){
                flag=1;fpr=i;
            }
            if(flag) fvis[i]=1,pr[i]=fpr;
        }
        ll ans=0;
        construct_sa(s,n+1,128);
        construct_lcp(s,n);
        for(int i=0;i<=n;i++){
            if(fvis[sa[i]]) ans=ans+n-max((sa[i]+height[i]),pr[sa[i]]);
        }
        printf("Case #%d: %I64d\n",cas++,ans);
    }
    return 0;
}

12.计算几何通用类

#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
#include <algorithm>
#define MAX 111116
#define eps 1e-7
using namespace std;
int sgn(const double &x){ return x < -eps? -1 : (x > eps);}
inline double sqr(const double &x){ return x * x;}
inline int gcd(int a, int b){ return !b? a: gcd(b, a % b);}
struct Point
{
    double x, y;
    Point(){}
    Point(const double &x, const double &y):x(x), y(y){}
    Point operator -(const Point &a)const{ return Point(x - a.x, y - a.y); }
    Point operator +(const Point &a)const{ return Point(x + a.x, y + a.y); }
    Point operator * (const double &a)const{ return Point(x * a, y * a); }
    Point operator / (const double &a)const{ return Point(x / a, y / a); }
    friend double det(const Point &a, const Point &b){ return a.x * b.y - a.y * b.x;}
    friend double dot(const Point &a, const Point &b){ return a.x * b.x + a.y * b.y;}
    friend double dist(const Point &a, const Point &b){ return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));}
    void in(){ scanf("%lf %lf", &x, &y); }
    void out(){ printf("%.2f %.2f\n", x, y); }
};
struct Line
{
    Point s, t;
    Line() {}
    Line(const Point &s, const Point &t):s(s), t(t) {}
    void in() { s.in(),t.in(); }
    double pointDistLine(const Point &p)
    {
        if(sgn(dot(t - s, p - s)) < 0)return dist(p, s);
        if(sgn(dot( s - t, p - t)) < 0)return dist(p, t);
        return fabs(det(t - s, p - s)) / dist(s, t);
    }
    bool pointOnLine(const Point &p)
    {
        return sgn(det(t - s, p - s)) == 0 && sgn(dot(s - p, t - p)) <= 0;
    }
};
struct Poly //多边形类
{
    vector<Point>a;
    void in(const int &r)
    {
        a.resize(r);
        for(int i = 0; i < r; i++) a[i].in();
    }

    //计算多边形的周长
    double perimeter()
    {
        double sum=0;
        int n=a.size();
        for(int i=0;i<n;i++) sum+=dist(a[i],a[(i+1)%n]);
        return sum;
    }

    //计算多边形的面积
    double getDArea()
    {
        int n = a.size();
        double ans = 0;
        for(int i = 0; i < n; i++) ans += det(a[i], a[(i + 1)%n]);
        return ans / 2;
    }

    //计算多边形的重心坐标
    Point getMassCenter()
    {
        Point center(0, 0);
        if(sgn(getDArea())==0) return center; //面积为0情况,当然这题说了面积不可能为0可不写
        int n = a.size();
        for(int i = 0; i < n; i++)
            center =center + (a[i] + a[(i + 1) % n]) * det(a[i], a[(i + 1) % n]);
        return center / getDArea() / 6;
    }

    //计算点t是否在多边形内,返回0指在外,1指在内,2指在边界上
    int pointOnline(Point t)
    {
        int num=0,i,d1,d2,k,n=a.size();
        for(i=0;i<n;i++)
        {
            Line line=Line(a[i],a[(i+1)%n]);
            if(line.pointOnLine(t)) return 2;
            k=sgn(det(a[(i+1)%n]-a[i],t-a[i]));
            d1=sgn(a[i].y-t.y);
            d2=sgn(a[(i+1)%n].y-t.y);
            if(k>0&&d1<=0&&d2>0) num++;
            if(k<0&&d2<=0&&d1>0) num--;
        }
        return num!=0;
    }
}poly;

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        cin>>n;
        poly.in(n);
        poly.getMassCenter().out();
    }
    return 0;
}

13.矩阵快速幂

#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")

using namespace std;
#define   MAX           200005
#define   MAXN          1000005
#define   maxnode       205
#define   sigma_size    26
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   lrt           rt<<1
#define   rrt           rt<<1|1
#define   middle        int m=(r+l)>>1
#define   LL            long long
#define   ull           unsigned long long
#define   mem(x,v)      memset(x,v,sizeof(x))
#define   lowbit(x)     (x&-x)
#define   pii           pair<int,int>
#define   bits(a)       __builtin_popcount(a)
#define   mk            make_pair
#define   limit         10000

//const int    prime = 999983;
const int    INF   = 0x3f3f3f3f;
const LL     INFF  = 0x3f3f;
const double pi    = acos(-1.0);
const double inf   = 1e18;
const double eps   = 1e-4;
const LL    mod    = 1e9+7;
const ull    mx    = 133333331;


struct Matrix{
    int n;
    LL maze[maxnode][maxnode];

    void init(int n)
    {
        this->n = n;
        mem(maze,0);
    }
    Matrix operator * (Matrix &rhs)
    {
        Matrix m;
        m.init(n);
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                for(int k=0;k<n;k++)
                    m.maze[i][j] = (m.maze[i][j] + maze[i][k] * rhs.maze[k][j])%mod;
        return m;
    }
};
int k;
LL qpow(Matrix a,int n)
{
    Matrix ans;
    ans.init(a.n);
    for(int i=0;i<ans.n;i++)
        ans.maze[i][i] = 1;
    while(n)
    {
        if(n&1) ans = ans * a;
        a = a*a;
        n >>= 1;
    }
    LL sum=0;
    for (int i=0;i<ans.n;i++)
    {
        sum+=ans.maze[i][0];
        sum%=mod;
    }

    return sum;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        scanf("%d%d%d",&n,&m,&k);
        Matrix A;
        A.init(m+1);
        for (int i=0;i<=m;i++)
            A.maze[0][i]=k*k-k;
        for (int i=0;i<=m;i++)
            A.maze[i+1][i]=k;
        LL ans=qpow(A,n);
        A.init(m);
        for (int i=0;i<m;i++)
            A.maze[0][i]=k*k-k;
        for (int i=0;i<m;i++)
            A.maze[i+1][i]=k;
        ans=(ans-qpow(A,n)+mod)%mod;
        printf("%lld\n",ans);
    }
    return 0;
}

14.快速傅里叶变换 (FFT)

/*
    algorithm : High-Precision FFT

*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define N 200005
#define pi acos(-1.0) // PI值
using namespace std;
struct complex
{
    double r,i;
    complex(double real=0.0,double image=0.0){
        r=real; i=image;
    }
    // 以下为三种虚数运算的定义
    complex operator + (const complex o){
        return complex(r+o.r,i+o.i);
    }
    complex operator - (const complex o){
        return complex(r-o.r,i-o.i);
    }
    complex operator * (const complex o){
        return complex(r*o.r-i*o.i,r*o.i+i*o.r);
    }
}x1[N],x2[N];
char a[N/2],b[N/2];
int sum[N]; // 结果存在sum里
void brc(complex *y,int l) // 二进制平摊反转置换 O(logn)
{
    register int i,j,k;
    for(i=1,j=l/2;i<l-1;i++)
    {
        if(i<j) swap(y[i],y[j]); // 交换互为下标反转的元素
                                // i<j保证只交换一次
        k=l/2;
        while(j>=k) // 由最高位检索,遇1变0,遇0变1,跳出
        {
            j-=k;
            k/=2;
        }
        if(j<k) j+=k;
    }
}
void fft(complex *y,int l,double on) // FFT O(nlogn)
                            // 其中on==1时为DFT,on==-1为IDFT
{
    register int h,i,j,k;
    complex u,t; 
    brc(y,l); // 调用反转置换
    for(h=2;h<=l;h<<=1) // 控制层数
    {
        // 初始化单位复根
        complex wn(cos(on*2*pi/h),sin(on*2*pi/h));
        for(j=0;j<l;j+=h) // 控制起始下标
        {
            complex w(1,0); // 初始化螺旋因子
            for(k=j;k<j+h/2;k++) // 配对
            {
                u=y[k];
                t=w*y[k+h/2];
                y[k]=u+t;
                y[k+h/2]=u-t;
                w=w*wn; // 更新螺旋因子
            } // 据说上面的操作叫蝴蝶操作…
        }
    }
    if(on==-1)  for(i=0;i<l;i++)    y[i].r/=l; // IDFT
}
int main(void)
{
    int l1,l2,l;
    register int i;
    while(scanf("%s%s",a,b)!=EOF)
    {
        l1=strlen(a);
        l2=strlen(b);
        l=1;
        while(l<l1*2 || l<l2*2) l<<=1; // 将次数界变成2^n
                                        // 配合二分与反转置换
        for(i=0;i<l1;i++) // 倒置存入
        {
            x1[i].r=a[l1-i-1]-'0';
            x1[i].i=0.0;
        }
        for(;i<l;i++)   x1[i].r=x1[i].i=0.0;
        // 将多余次数界初始化为0
        for(i=0;i<l2;i++)
        {
            x2[i].r=b[l2-i-1]-'0';
            x2[i].i=0.0;
        }
        for(;i<l;i++)   x2[i].r=x2[i].i=0.0;
        fft(x1,l,1); // DFT(a)
        fft(x2,l,1); // DFT(b)
        for(i=0;i<l;i++)    x1[i]=x1[i]*x2[i]; // 点乘结果存入a
        fft(x1,l,-1); // IDFT(a*b)
        for(i=0;i<l;i++)    sum[i]=x1[i].r+0.5; // 四舍五入
        for(i=0;i<l;i++) // 进位
        {
            sum[i+1]+=sum[i]/10;
            sum[i]%=10;
        }
        l=l1+l2-1;
        while(sum[l]<=0 && l>0) l--; // 检索最高位
        for(i=l;i>=0;i--)   putchar(sum[i]+'0'); // 倒序输出
        putchar('\n');
    }
    return 0;
}

15.快速数论变换 NTT

/*
1.快速傅里叶变换适用于所有复数,但是存在精度问题。
2.数论变换只能用于整数,但是速度会更快,可有准确求出卷积。
3.数组常开n的4倍。
*/
//NTT
const long long P = 50000000001507329LL; //190734863287 * 2 ^ 18 + 1
const int G = 3;//P的原根

long long wn[25];//此时应该大于18

long long mul(long long x, long long y) {
    return (x*y - (long long)(x / (long double)P*y + 1e-3) * P + P) % P;
}//保证求余时两个数都是正的,处理精度问题

long long qpow(long long x, long long k) {
    long long ret = 1;
    while(k) {
        if(k & 1) ret = mul(ret, x);
        k >>= 1;
        x = mul(x, x);
    }
    return ret;
}

void getwn() {
    for(int i = 1; i <= 18; ++i) {
        int t = 1 << i;
        wn[i] = qpow(G, (P - 1)/t);
    }
}
int len;
void change(long long y[], int len) {
    for(int i = 1, j = len/2; i < len - 1; ++i) {
        if(i < j) swap(y[i], y[j]);
        int k = len/2;
        while(j >= k) {
            j -= k;
            k /= 2;
        }
        j += k;
    }
}

void NTT(long long y[], int on) {
    change(y, len);
    int id = 0;

    for(int h = 2; h <= len; h <<= 1) {
        ++id;
        for(int j = 0; j < len; j += h) {
            long long w = 1;
            for(int k = j; k < j + h / 2; ++k) {
                long long u = y[k];
                long long t = mul(y[k+h/2], w);
                y[k] = u + t;
                if(y[k] >= P) y[k] -= P;
                y[k+h/2] = u - t + P;
                if(y[k+h/2] >= P) y[k+h/2] -= P;
                w = mul(w, wn[id]);
            }
        }
    }
    if(on == -1) {
        for(int i = 1; i < len / 2; ++i) swap(y[i], y[len-i]);
        long long inv = qpow(len, P - 2);
        for(int i = 0; i < len; ++i)
            y[i] = mul(y[i], inv);
    }
}
void Convolution(long long A[],long long B[],int n){
    for(len=1; len<(n<<1); len<<=1);
    for(int i=n; i<len; ++i){
        A[i]=B[i]=0;
    }

    NTT(A,1); NTT(B,1);
    for(int i=0; i<len; ++i){
        A[i]=mul(A[i],B[i]);
    }
    NTT(A,-1);
}

16.读入外挂

inline int getint()
{
       int w=0,q=0;
       char c=getchar();
       while((c<'0' || c>'9') && c!='-') c=getchar();
       if (c=='-')  q=1, c=getchar();
       while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
       return q ? -w : w;
}

我可是有底线的(  ̄▽ ̄)((≧︶≦)


2B桑

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值