zoukankan      html  css  js  c++  java
  • Template.

    Background

    还有一个礼拜就省选了,连板子都不会打的Zars19觉得应该来一次模板补全计划。

    (尽管好多该学的东西还没学)

    Update:省选已经完了…但是还没补全

    1.0 树链剖分(BZOJ1036 [ZJOI2008]树的统计Count)

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #define INF 0x3f3f3f3f
    #define MAXN 30005
    using namespace std;
    int n,q,sz=0,head[MAXN],w[MAXN],ans;
    int dep[MAXN],top[MAXN],pos[MAXN],num[MAXN],father[MAXN],siz[MAXN],cnt=0;
    struct Node1
    {
        int next,to;
    }Edges[MAXN*2];
    void addedge(int u,int v)
    {
        Edges[++cnt].next=head[u];
        head[u]=cnt;
        Edges[cnt].to=v;
    }
    int read()
    {
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')f=-1;c=getchar();
        }
        while(c>='0'&&c<='9'){
            x=x*10+c-'0';c=getchar();
        }
        return x*f;
    }
    void dfs1(int u)
    {
        siz[u]=1;
        for(int i=head[u];~i;i=Edges[i].next)
        {
            int v=Edges[i].to;
            if(v==father[u])continue;
            father[v]=u,dep[v]=dep[u]+1;
            dfs1(v);
            siz[u]+=siz[v];
        }
    }
    void dfs2(int u,int t)
    {
        sz++,pos[u]=sz,num[sz]=u;
        int maxv=0,k=0;
        top[u]=t;
        for(int i=head[u];~i;i=Edges[i].next)
        {
            int v=Edges[i].to;
            if(v==father[u])continue;
            if(siz[v]>maxv)maxv=siz[v],k=v;
        }
        if(k)dfs2(k,t);
        for(int i=head[u];~i;i=Edges[i].next)
        {
            int v=Edges[i].to;
            if(v==father[u]||v==k)continue;
            dfs2(v,v);
        }
    }
    struct Node2
    {
        int l,r,sum,maxn;
    }t[MAXN*4];
    void build(int idx,int l,int r)
    {
        t[idx].l=l,t[idx].r=r;
        if(l==r)
        {
            t[idx].sum=t[idx].maxn=w[num[l]];
            return;
        }
        int mid=(l+r)>>1;
        build(idx<<1,l,mid);
        build(idx<<1|1,mid+1,r);
        t[idx].maxn=max(t[idx<<1].maxn,t[idx<<1|1].maxn);
        t[idx].sum=t[idx<<1].sum+t[idx<<1|1].sum;
    }
    int query1(int idx,int a,int b)
    {
        if(a<=t[idx].l&&b>=t[idx].r)
        return t[idx].maxn;
        int mid=(t[idx].l+t[idx].r)>>1;
        if(b<=mid)return query1(idx<<1,a,b);
        if(a>mid)return query1(idx<<1|1,a,b);
        return max(query1(idx<<1,a,b),query1(idx<<1|1,a,b));
    }
    int query2(int idx,int a,int b)
    {
        if(a<=t[idx].l&&b>=t[idx].r)
        return t[idx].sum;
        int mid=(t[idx].l+t[idx].r)>>1;
        if(b<=mid)return query2(idx<<1,a,b);
        if(a>mid)return query2(idx<<1|1,a,b);
        return query2(idx<<1,a,b)+query2(idx<<1|1,a,b);
    }
    void change(int idx,int a,int b)
    {
        if(t[idx].l==t[idx].r){t[idx].maxn=t[idx].sum=b;return;}
        int mid=(t[idx].l+t[idx].r)>>1;
        if(a<=mid)change(idx<<1,a,b);
        else change(idx<<1|1,a,b);
        t[idx].maxn=max(t[idx<<1].maxn,t[idx<<1|1].maxn);
        t[idx].sum=t[idx<<1].sum+t[idx<<1|1].sum;
    }
    void QMAX(int a,int b)
    {
        ans=-INF;
        while(top[a]!=top[b])
        {
            if(dep[top[a]]<dep[top[b]])swap(a,b);
            ans=max(ans,query1(1,pos[top[a]],pos[a]));
            a=father[top[a]];
        }
        if(pos[a]>pos[b])swap(a,b);
        ans=max(ans,query1(1,pos[a],pos[b]));
        printf("%d
    ",ans);
    }
    void QSUM(int a,int b)
    {
        ans=0;
        while(top[a]!=top[b])
        {
            if(dep[top[a]]<dep[top[b]])swap(a,b);
            ans+=query2(1,pos[top[a]],pos[a]);
            a=father[top[a]];
        }
        if(pos[a]>pos[b])swap(a,b);
        ans+=query2(1,pos[a],pos[b]);
        printf("%d
    ",ans);
    } 
    int main()
    {
        memset(head,-1,sizeof(head));
        n=read();
        for(int i=1;i<n;i++)
        {
            int a=read(),b=read();
            addedge(a,b);
            addedge(b,a);
        }
        for(int i=1;i<=n;i++)
        w[i]=read();
        dfs1(1);dfs2(1,1);
        build(1,1,sz);
        q=read();
        char opt[10];int a,b;
        for(int i=1;i<=q;i++)
        {
            scanf("%s",opt);
            a=read(),b=read();
            if(!strcmp(opt,"CHANGE"))
            change(1,pos[a],b);
            else if(!strcmp(opt,"QMAX"))
            QMAX(a,b);
            else 
            QSUM(a,b);
        }
        return 0;
    } 
    View Code

    2.0 Tarjan离线LCA

    2.1 倍增LCA

    3.0 点分治(BZOJ2152 聪聪可可)

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #define MAXN 20005
    #define INF 0x3f3f3f3f
    using namespace std;
    int n,head[MAXN],siz[MAXN],maxv[MAXN],root=0,tot=0,num=0,cnt=0,t[3],p,q;
    bool vis[MAXN];
    int read()
    {
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    struct Node
    {
        int next,to,w;
    }Edges[MAXN*2];
    int gcd(int a,int b){return b?gcd(b,a%b):a;}
    void addedge(int u,int v,int w)
    {
        Edges[cnt].next=head[u];
        head[u]=cnt;
        Edges[cnt].to=v;
        Edges[cnt++].w=w;
    }
    void getroot(int u,int f)
    {
        siz[u]=1,maxv[u]=0;
        for(int i=head[u];~i;i=Edges[i].next)
        {
            int v=Edges[i].to;
            if(v==f||vis[v])continue;
            getroot(v,u);
            siz[u]+=siz[v],maxv[u]=max(maxv[u],siz[v]);
        }
        maxv[u]=max(maxv[u],tot-siz[u]);
        if(maxv[u]<maxv[root])root=u;
    }
    void getdeep(int u,int f,int d)
    {
         t[d]++;
         for(int i=head[u];~i;i=Edges[i].next)
         {
             int v=Edges[i].to;
             if(v==f||vis[v])continue;
             getdeep(v,u,(d+Edges[i].w)%3);
         }
    }
    int calc(int u,int d)
    {
        memset(t,0,sizeof(t));
        getdeep(u,0,d);
        return t[0]*t[0]+t[1]*t[2]*2;
    }
    void work(int u)
    {
        vis[u]=1;p+=calc(u,0);
        for(int i=head[u];~i;i=Edges[i].next)
        {
            int v=Edges[i].to;
            if(vis[v])continue;
            p-=calc(v,Edges[i].w%3);
            tot=siz[v],root=0;
            getroot(v,u),work(root);
        }
    }
    int main()
    {
        memset(head,-1,sizeof(head));
        n=read();
        for(int i=1;i<n;i++)
        {
            int u=read(),v=read(),w=read();
            addedge(u,v,w),addedge(v,u,w);
        }
        maxv[0]=INF,tot=n;
        p=0,q=n*n;
        getroot(1,0),work(1);
        int t=gcd(p,q);
        printf("%d/%d
    ",p/t,q/t);
        return 0;
    }
    View Code

    数据结构

    1.0 splay(BZOJ3223 Tyvj 1729 文艺平衡树)

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    using namespace std;
    int n,m,a[100005],root,siz=0;
    struct Node{
        int ch[2],father,val,rev,siz;
    }t[100005];
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')f=-1;c=getchar();
        }
        while(c>='0'&&c<='9'){
            x=x*10+c-'0';c=getchar();
        }
        return x*f;
    }
    void Update(int x)
    {
        t[x].siz=t[t[x].ch[0]].siz+t[t[x].ch[1]].siz+1;
    }
    void Pushdown(int x)
    {
        if(t[x].rev)
        {
            t[x].rev=0;
            if(t[x].ch[0])t[t[x].ch[0]].rev^=1;
            if(t[x].ch[1])t[t[x].ch[1]].rev^=1;
            swap(t[x].ch[0],t[x].ch[1]);
        }
    }
    void Rotate(int x,int &k)
    {
        Pushdown(x);
        int y=t[x].father,z=t[y].father;
        int p=(t[y].ch[0]==x)?0:1;
        if(y!=k)
        {
            if(t[z].ch[0]==y)t[z].ch[0]=x;
            else t[z].ch[1]=x;
        }
        else k=x;
        t[x].father=z;
        t[y].ch[p]=t[x].ch[p^1];
        t[t[x].ch[p^1]].father=y;
        t[x].ch[p^1]=y;
        t[y].father=x;
        Update(y),Update(x);
    }
    void Splay(int x,int &k)
    {
        while(x!=k)
        {
            int y=t[x].father,z=t[y].father;
            if(y!=k)
            {
                if((t[y].ch[0]==x)^(t[z].ch[0]==y))
                Rotate(x,k);
                else Rotate(y,k);
            }
            Rotate(x,k);
        }
    }
    int Build(int l,int r,int f)
    {
        if(l>r)return 0;
        int mid=(l+r)>>1,now=++siz;
        t[now].father=f;
        t[now].rev=0;
        t[now].val=mid;
        t[now].ch[0]=Build(l,mid-1,now);
        t[now].ch[1]=Build(mid+1,r,now);
        Update(now);
        return now;
    }
    int Find(int x,int k)
    {
        if(!k)return 0;
        Pushdown(x);
        if(t[t[x].ch[0]].siz>=k)return Find(t[x].ch[0],k);
        else if(t[t[x].ch[0]].siz+1<k)return Find(t[x].ch[1],k-t[t[x].ch[0]].siz-1);
        return x;
    }
    void Print(int k)
    {
        if(!k)return;
        Pushdown(k);
        Print(t[k].ch[0]);
        if(t[k].val!=0&&t[k].val!=n+1)
        printf("%d ",t[k].val);
        Print(t[k].ch[1]);
    } 
    int main()
    {
        n=read(),m=read();
        root=Build(0,n+1,0);
        for(int i=1;i<=m;i++)
        {
            int l,r;
            l=read(),r=read();
            int x=Find(root,l),y=Find(root,r+2);
            Splay(x,root);Splay(y,t[root].ch[1]);
            t[t[y].ch[0]].rev^=1;
        }Print(root);
        return 0;
    }
    View Code

    1.1 treap(BZOJ3224 TYVJ 1728 普通平衡树)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<ctime>
    using namespace std;
    int n,siz=0,root=0,ans;
    struct Node
    {
        int lch,rch,val,siz,w,rank;
    }t[100005];
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')f=-1;c=getchar();
        }
        while(c>='0'&&c<='9'){
            x=x*10+c-'0';c=getchar(); 
        }
        return x*f;
    }
    void update(int k)
    {
        t[k].siz=t[t[k].lch].siz+t[t[k].rch].siz+t[k].w;
    }
    void leftRotate(int &k)
    {
        int p=t[k].rch;
        t[k].rch=t[p].lch;
        t[p].lch=k;
        t[p].siz=t[k].siz;
        update(k);k=p;
    }
    void rightRotate(int &k)
    {
        int p=t[k].lch;
        t[k].lch=t[p].rch;
        t[p].rch=k;
        t[p].siz=t[k].siz;
        update(k);k=p;
    }
    void Insert(int &k,int x)
    {
        if(!k){
            siz++;k=siz;
            t[k].siz=t[k].w=1;
            t[k].val=x;
            t[k].rank=rand();
            return;
        }
        t[k].siz++;
        if(t[k].val==x)
        {t[k].w++;return;}
        if(x<t[k].val){
            Insert(t[k].lch,x);
            if(t[t[k].lch].rank<t[k].rank)rightRotate(k);
            return;
        }
        else{
            Insert(t[k].rch,x);
            if(t[t[k].rch].rank<t[k].rank)leftRotate(k);
            return;
        }
    }
    void Delete(int &k,int x)
    {
        if(!k)return;
        if(t[k].val==x)
        {
            if(t[k].w>1)
            {t[k].siz--;t[k].w--;return;}
            if(!t[k].lch||!t[k].rch)
            {k=t[k].lch+t[k].rch;return;}
            if(t[t[k].lch].rank>t[t[k].rch].rank){
                leftRotate(k);Delete(k,x);
                return;
            }
            else{
                rightRotate(k);Delete(k,x);
                return;
            }
        }
        t[k].siz--;
        if(x<t[k].val){
            Delete(t[k].lch,x);
            return;
        }
        else{
            Delete(t[k].rch,x);
            return;
        }
    }
    int queryRank(int k,int x)
    {
        if(!k)return 0;
        if(x==t[k].val)return t[t[k].lch].siz+1;
        else if(x<t[k].val)return queryRank(t[k].lch,x);
        else return t[t[k].lch].siz+t[k].w+queryRank(t[k].rch,x);
    }
    int queryNum(int k,int x)
    {
        if(!k)return 0;
        if(x<=t[t[k].lch].siz)return queryNum(t[k].lch,x);
        else if(x>t[t[k].lch].siz+t[k].w)return queryNum(t[k].rch,x-t[t[k].lch].siz-t[k].w);
        else return t[k].val;
    }
    void queryPre(int k,int x)
    {
        if(!k)return;
        if(x<=t[k].val)queryPre(t[k].lch,x);
        else {ans=t[k].val,queryPre(t[k].rch,x);}
    }
    void querySuc(int k,int x)
    {
        if(!k)return;
        if(x>=t[k].val)querySuc(t[k].rch,x);
        else {ans=t[k].val,querySuc(t[k].lch,x);}
    }
    int main()
    {
        srand(time(0));
        n=read();
        for(int i=1;i<=n;i++)
        {
            int opt,x;
            opt=read(),x=read();
            switch(opt)
            {
                case 1:Insert(root,x);break;
                case 2:Delete(root,x);break;
                case 3:printf("%d
    ",queryRank(root,x));break;
                case 4:printf("%d
    ",queryNum(root,x));break;
                case 5:ans=0;queryPre(root,x);printf("%d
    ",ans);break;
                case 6:ans=0;querySuc(root,x);printf("%d
    ",ans);break;
            }
        }
        return 0;
    }
    View Code

    图论

    1.0 强连通分量

    void tarjan(int u)
    {
        dfn[u]=low[u]=++dfn_clock;
        vis[u]=ins[u]=1;s.push(u);
        for(int i=head[u];~i;i=Edges[i].next)
        {
            int v=Edges[i].to;
            if(!vis[v])
            {
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else if(ins[v])
            {low[u]=min(low[u],dfn[v]);}
        }
        if(dfn[u]==low[u])
        {
            tot++;int t=-1;
            while(t!=u)
            {
                t=s.top();
                sccno[t]=tot;
                ins[t]=0;
                s.pop();
            }
        }
    }
    View Code

    1.1 割点

    1.2 割边

    2.0 Dinic (草地排水)

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #define INF 0x3f3f3f3f
    #define MAXN 250
    using namespace std;
    int m,n,s,t,level[MAXN],head[MAXN],cnt=0;
    struct Node{
        int next,to,cap;
    }Edges[MAXN*2];
    void addedge(int u,int v,int c)
    {
        Edges[cnt].next=head[u];
        head[u]=cnt;
        Edges[cnt].to=v;
        Edges[cnt++].cap=c;
    }
    void insert(int u,int v,int c){
        addedge(u,v,c);
        addedge(v,u,0);
    }
    bool bfs()
    {
        memset(level,-1,sizeof(level));
        level[s]=0;
        queue<int>q;
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();q.pop();
            for(int i=head[u];~i;i=Edges[i].next)
            {
                int v=Edges[i].to;
                if(level[v]==-1&&Edges[i].cap)
                level[v]=level[u]+1,q.push(v);
            }
        }
        if(level[t]==-1)return false;
        return true;
    }
    int dfs(int u,int flow)
    {
        int f=0,d=0;
        if(u==t)return flow;
        for(int i=head[u];~i&&flow>f;i=Edges[i].next)
        {
            int v=Edges[i].to;
            if(level[v]==level[u]+1&&Edges[i].cap)
            {
                d=dfs(v,min(flow-f,Edges[i].cap));
                f+=d;
                Edges[i].cap-=d;
                Edges[i^1].cap+=d;
            }
        }
        if(!f)level[u]=-1;
        return f;
    }
    int main()
    {
        memset(head,-1,sizeof(head));
        scanf("%d%d",&m,&n);
        s=1,t=n;
        for(int i=1;i<=m;i++)
        {
            int u,v,c;
            scanf("%d%d%d",&u,&v,&c);
            insert(u,v,c);
        }
        int ans=0,d;
        while(bfs())
        {
            while(d=dfs(s,INF))
            ans+=d;
        }
        printf("%d",ans);
        return 0;
    } 
    View Code

    2.1 费用流

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<queue>
    #define INF 0x3f3f3f3f
    using namespace std;
    int m,n,s,t,a[450],pre[450],dis[450],head[450],cnt=0,MF,MC;
    bool inq[450];
    struct Node{
        int next,from,to,cap,w;
    }Edges[30005];
    void addedge(int u,int v,int c,int w)
    {
        Edges[cnt].next=head[u];
        head[u]=cnt;
        Edges[cnt].from=u;
        Edges[cnt].to=v;
        Edges[cnt].cap=c;
        Edges[cnt++].w=w;
    }
    void insert(int u,int v,int c,int w){
        addedge(u,v,c,w);
        addedge(v,u,0,-w);
    }
    void MCMF()
    {
        MF,MC=0;
        while(1)
        {
            memset(dis,0x3f,sizeof(dis));
            memset(a,0,sizeof(a));
            int f=0;
            queue<int>q;
            q.push(s);
            inq[s]=1,a[s]=INF,dis[s]=0;
            while(!q.empty())
            {
                int u=q.front();q.pop();inq[u]=0;
                for(int i=head[u];~i;i=Edges[i].next)
                {
                    int v=Edges[i].to;
                    if(dis[u]+Edges[i].w<dis[v]&&Edges[i].cap>0)
                    {
                        dis[v]=dis[u]+Edges[i].w;
                        a[v]=min(a[u],Edges[i].cap);
                        pre[v]=i;
                        if(!inq[v]){q.push(v);inq[v]=1;}
                    }
                }
            }
            if(a[t]==0)break;
            int p=t;
            MC+=a[t]*dis[t];
            while(p!=s){
                Edges[pre[p]].cap-=a[t];
                Edges[pre[p]^1].cap+=a[t];
                p=Edges[pre[p]].from;
            }
            MF+=a[t];
            
        }
    }
    int main()
    {
        memset(head,-1,sizeof(head));
        scanf("%d%d",&n,&m);
        s=1,t=n;
        for(int i=1;i<=m;i++)
        {
            int u,v,c,w;
            scanf("%d%d%d%d",&u,&v,&c,&w);
            insert(u,v,c,w);
        }
        MCMF();
        printf("%d %d
    ",MF,MC);
        return 0;
    } 
    View Code

    3.0 匈牙利算法(UOJ#78. 二分图最大匹配)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    using namespace std;
    int n1,n2,m,head[505],cnt=0,ans=0,link[505];
    bool vis[505];
    struct Node
    {
        int next,to;
    }Edges[250005];
    void addedge(int u,int v)
    {
        Edges[++cnt].next=head[u];
        head[u]=cnt;
        Edges[cnt].to=v;
    }
    int read()
    {
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')f=-1;c=getchar();
        }
        while(c>='0'&&c<='9'){
            x=x*10+c-'0';c=getchar();
        }
        return x*f;
    }
    bool dfs(int u)
    {
        for(int i=head[u];~i;i=Edges[i].next)
        {
            int v=Edges[i].to;
            if(!vis[v])
            {
                vis[v]=1;
                if(!link[v]||dfs(link[v]))
                {link[v]=u;return true;}
            }
        }
        return false;
    }
    int main()
    {
        memset(head,-1,sizeof(head));
        n1=read(),n2=read(),m=read();
        for(int i=1;i<=m;i++)
        {
            int v=read(),u=read();
            addedge(u,v);
        }
        for(int i=1;i<=n2;i++)
        {
            memset(vis,0,sizeof(vis));
            if(dfs(i))ans++;
        }
        printf("%d
    ",ans);
        for(int i=1;i<=n1;i++)
        printf("%d ",link[i]);
        return 0;
    } 
    View Code

    字符串

    1.0 KMP

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #define MAXN 1000005
    using namespace std;
    int n,m,next[MAXN],cnt=0;
    char a[MAXN],b[MAXN];
    int main()
    {
        scanf("%s%s",a+1,b+1);
        n=strlen(a+1),m=strlen(b+1);
        int j=0;next[1]=0;
        for(int i=2;i<=m;i++)
        {
            while(j!=0&&b[i]!=b[j+1])j=next[j];
            if(b[i]==b[j+1])j++;
            next[i]=j;
        }
        j=0;
        for(int i=1;i<=n;i++)
        {
            while(j!=0&&a[i]!=b[j+1])j=next[j];
            if(a[i]==b[j+1])j++;
            if(j==m){j=next[j],++cnt;}
        }
        printf("%d
    ",cnt);
        return 0;
    }
    View Code

    2.0 AC自动机(BZOJ3172 TJOI2013 单词)

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    using namespace std;
    int n,siz,root,q[1000010],head,tail,pos[202];
    char word[1000010];
    struct Node{
        int next[26],cnt,fail;
        bool vis;
    }trie[1000010];
    int newnode()
    {
        siz++;
        trie[siz].cnt=trie[siz].fail=trie[siz].vis=0;
        memset(trie[siz].next,0,sizeof(trie[siz].next));
        return siz;
    }
    void insert(int x,char* word)
    {
        int i=0,p=root;
        while(word[i])
        {
            int idx=word[i]-'a';
            if(!trie[p].next[idx])trie[p].next[idx]=newnode();
            p=trie[p].next[idx];
            trie[p].cnt++;
            i++;
        }
        pos[x]=p;
    }
    void build()
    {
        head=0,tail=0;
        q[++tail]=root;
        while(head<tail)
        {
            int p=q[++head];
            for(int i=0;i<26;i++)
            {
                int t=trie[p].fail;
                while(t&&!trie[t].next[i])t=trie[t].fail;
                if(trie[p].next[i])
                {
                    trie[trie[p].next[i]].fail=t?trie[t].next[i]:root;
                    q[++tail]=trie[p].next[i];
                }
                else trie[p].next[i]=t?trie[t].next[i]:root;
            }
        }
    }
    void work()
    {
        int res=0;
        for(int p=tail;p>0;p--)
        {
            int t=trie[q[p]].fail;
            trie[t].cnt+=trie[q[p]].cnt;
        }
        for(int i=1;i<=n;i++)
        printf("%d
    ",trie[pos[i]].cnt);
    }
    int main()
    {
        scanf("%d",&n);
        siz=0,root=newnode();
        for(int i=1;i<=n;i++)
        {
            scanf("%s",word);
            insert(i,word);
        }
        build();work();
        return 0;
    }
    View Code

    3.0 Manachar

    4.0 SAM

    5.0 SA

    计算几何

    1.0 点和直线

    int dcmp(double x){        //实数比较 
        if(fabs(x)<EPS)return 0;
        return x>0?1:-1;
    }
    struct Point{        //点向量的定义 
        double x,y;
        Point(double x=0,double y=0):x(x),y(y){}
        Point operator + (Point A){return Point(x+A.x,y+A.y);}
        Point operator - (Point A){return Point(x-A.x,y-A.y);}
        Point operator * (double p){return Point(x*p,y*p);}
        Point operator / (double p){return Point(x/p,x/p);}    
        bool operator == (Point A){return dcmp(x-A.x)==0&&dcmp(y-A.y)==0;}
    };
    typedef Point Vector;
    double dot(Vector A,Vector B){        //点积 
        return A.x*B.x+A.y*B.y;
    }
    double cross(Vector A,Vector B){    //叉积 
        return A.x*B.y-B.x*A.y;
    }
    double length(Vector A){        //向量的长度 
        return sqrt(dot(A,A));
    }
    double angle(Vector A,Vector B){        //两向量的转角 
        return acos(dot(A,B)/length(A)/length(B));
    }
    Vector rotate(Vector A,double rad){        //向量的旋转 
        return Vector(cos(rad)*A.x-sin(rad)*A.y,sin(rad)*A.x+cos(rad)*A.y);
    }
    Vector normal(Vector A){        //法向量 
        double l=length(A);
        return Vector(-A.y/l,A.x/l);
    }
    struct Line{        //线 
        Point p;Vector v;
        Line(Point p=Point(0,0),Vector v=Vector(0,0)):p(p),v(v){}
    };
    Point get_intersection(Line A,Line B){        //两直线求交 
        Point u=A.p-B.p;
        double t=cross(B.v,u)/cross(A.v,B.v);
        return A.p+A.v*t;
    }
    double dis_line(Point P,Point A,Point B){        //点到直线的距离 
        Vector v1=B-A,v2=P-A;
        return fabs(cross(v1,v2)/length(v1));
    }
    double dis_segment(Point P,Point A,Point B){        //点到线段的距离 
        Vector v1=B-A,v2=P-A,v3=P-B;
        if(dcmp(dot(v1,v2)<0))return length(v2);
        if(dcmp(dot(v1,v3)>0))return length(v3); 
        return fabs(cross(v1,v2)/length(v1));
    }
    Point get_projection(Point P,Point A,Point B){        //点在直线上的投影 
        Vector v=B-A; 
        return A+v*(dot(P-A,v)/dot(v,v)); 
    } 
    bool segment_properintersection(Point a1,Point a2,Point b1,Point b2)    //线段相交判定 
    {
        double c1=cross(b2-b1,a1-b1),c2=cross(b2-b1,a2-b1),
        c3=cross(a2-a1,b1-a1),c4=cross(a2-a1,b2-a1);
        return dcmp(c1)*dcmp(c2)<=0&&dcmp(c3)*dcmp(c4)<=0;
    }
    View Code

    2.0 圆

    struct Circle{
        Point c;double r;
        Point getpoint(double ang){        //获取圆上弧度角为ang的点 
            return Point(c.x+r*cos(ang),c.y+r*sin(ang));
        }
    };
    int getLineCircle_intersection(Line L,Circle C,double& t1,double& t2,vector<Point>& sol){
        double a=L.v.x,b=L.p.x-C.c.x,c=L.v.y,d=L.p.y-C.c.y;        //直线与圆的交点 
        double e=a*a+c*c,f=2*a*b+2*c*d,g=b*b+d*d-C.r*C.r;
        double delta=(f*f)-4*e*g;
        if(dcmp(delta)<0)return 0;
        if(!dcmp(delta)){
            t1=-f/(2*e);sol.push_back(L.p+L.v*t1);
            return 1;
        }
        t1=-f+sqrt(delta)/(2*e);t2=-f-sqrt(delta)/(2*e);
        sol.push_back(L.p+L.v*t1);sol.push_back(L.p+L.v*t2);
        return 2;
    }
    double angle(Vector A){        //极角 
        return atan2(A.y,A.x);
    }
    int getCircleCircle_intersection(Circle C1,Circle C2,vector<Point>& sol){        
        double d=length(C1.c-C2.c);        //两圆交点 
        if(dcmp(C1.r+C2.r-d)<0)return 0;
        if(dcmp(fabs(C1.r-C2.r)-d)>0)return 0;
        double a=angle(C2.c-C1.c);
        double da=acos((d*d+C1.r*C1.r-C2.r*C2.r)/(2*d*C1.r));
        Point p1=C1.getpoint(a+da),p2=C1.getpoint(a-da);
        if(p1==p2){
            sol.push_back(p1);return 1;
        };
        sol.push_back(p1),sol.push_back(p2);
        return 2;
    }
    int get_tangents(Point p,Circle C,vector<Point>& sol){
        Vector u=C.c-p;        //切线 
        double dis=length(u);
        if(dcmp(dis-C.r)<0)return 0;
        if(!dcmp(dis-C.r)){
            sol.push_back(rotate(u,pi/2));return 1;
        }
        double ang=asin(C.r/dis);
        sol.push_back(rotate(u,ang));sol.push_back(rotate(u,-ang));
        return 2;
    }
    View Code

    3.0 凸包

    4.0 半平面交

    5.0 自适应Simpson积分

    double simpson(double a,double b){
        double c=a+(b-a)/2;
        return (F(a)+4*F(c)+F(b))*(b-a)/6.0;
    }
    double asr(double a,double b,double eps,double A){
        double c=a+(b-a)/2;
        double L=simpson(a,c),R=simpson(c,b);
        if(fabs(L+R-A)<eps*15)return (L+R)+(L+R-A)/15;
        return asr(a,c,eps/2,L)+asr(c,b,eps/2,R);
    }
    View Code

    6.0 旋转卡壳

    数学

    1.0 欧几里得算法

    LL gcd(LL a,LL b){
        return (b==0)?a:gcd(b,a%b);
    }
    View Code

    1.1 扩展欧几里得算法

    void exgcd(LL a,LL b,LL& d,LL& x,LL& y){
        if(!b){d=a,x=1,y=0;}
        else {exgcd(b,a%b,d,y,x);y-=x*(a/b);}
    }
    View Code

    2.0 乘法逆元

    LL inv(LL a,LL p){
        LL d,x,y;
        exgcd(a,p,d,x,y);
        return (d==1)?(x+p)%p:-1;
    }
    View Code

    3.0 FFT(UOJ#34. 多项式乘法)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #define MAXN 400005
    #define pi acos(-1)
    using namespace std;
    int n,m;
    struct cp
    {
        double r,i;
        cp(double r=0,double i=0):r(r),i(i){}
        cp operator + (const cp& A)
        {return cp(r+A.r,i+A.i);}
        cp operator - (const cp& A)
        {return cp(r-A.r,i-A.i);}
        cp operator * (const cp& A)
        {return cp(r*A.r-i*A.i,r*A.i+i*A.r);}
    }a[MAXN],b[MAXN];
    void brc(cp* x,int l)
    {
        int k=l/2;
        for(int i=1;i<l-1;i++)
        {
            if(i<k)swap(x[i],x[k]);
            int j=l/2;
            while(j<=k)
            {
                k-=j;
                j>>=1;
            }
            if(k<j)k+=j;
        }
    }
    void fft(cp* x,int l,int on)
    {
        brc(x,l);
        for(int h=2;h<=l;h<<=1)
        {
            cp wn(cos(2*on*pi/h),sin(2*on*pi/h));
            for(int i=0;i<l;i+=h)
            {
                cp w(1,0);
                for(int j=i;j<i+h/2;j++)
                {
                    cp u=x[j];
                    cp t=w*x[j+h/2];
                    x[j]=u+t;
                    x[j+h/2]=u-t;
                    w=w*wn;
                }
            }
        }
        if(on==-1)for(int i=0;i<l;i++)x[i].r/=l;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        n++,m++;
        int l=1;
        while(l<n*2||l<m*2)l<<=1;
        for(int i=0;i<n;i++)
        {
            int x;
            scanf("%d",&x);
            a[i]=cp(x,0);
        }
        for(int i=n;i<l;i++)a[i]=cp(0,0);
        for(int i=0;i<m;i++)
        {
            int x;
            scanf("%d",&x);
            b[i]=cp(x,0);
        }
        for(int i=m;i<l;i++)b[i]=cp(0,0);
        fft(a,l,1);fft(b,l,1);
        for(int i=0;i<l;i++)a[i]=a[i]*b[i];
        fft(a,l,-1);
        for(int i=0;i<=n+m-2;i++)
        {
            int x=(int)(a[i].r+0.5); 
            printf("%d ",x);
        }
        return 0;
    }
    View Code
    4.0 NTT
    5.0 欧拉函数
    void phi_table()
    {
        phi[1]=1;
        for(int i=1;i<=n;i++)
        {
            if(!phi[i])
            for(int j=i;j<=n;j+=i)
            {
                if(!phi[j])phi[j]=j;
                phi[j]=phi[j]*(i-1)/i;
            }
        }
    }
    View Code

    6.0 中国剩余定理(CodeVS 3990 中国余数定理 2)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    using namespace std;
    typedef long long LL;
    LL n,a,b,c[15],m[15],M=1,res=0;
    LL read()
    {
        LL x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    void exgcd(LL a,LL b,LL &x,LL &y)
    {
        if(!b)x=1,y=0;
        else exgcd(b,a%b,y,x),y-=x*(a/b);
    }
    int main()
    {
        n=read(),a=read(),b=read();
        for(int i=1;i<=n;i++)
        m[i]=read(),c[i]=read(),M*=m[i];
        for(int i=1;i<=n;i++)
        {
            LL t=M/m[i],x,y;
            exgcd(t,m[i],x,y);
            x=(x+m[i])%m[i];
            res=(res+((x*t)%M*c[i])%M)%M;
        }
        if(a>res)
        {
            if((a-res)%M==0)res+=(a-res)/M*M;
            else res+=((a-res)/M+1)*M;
        }
        if(res>b||res<a){printf("0
    0
    ");return 0;}
        printf("%lld
    %lld
    ",(b-res)/M+1,res);
        return 0;
    }
    View Code

    6.1 扩展中国剩余定理(POJ 2891 Strange Way to Express Integers

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #define MAXN 50005
    using namespace std;
    typedef long long LL;
    LL k,c[MAXN],m[MAXN];
    LL read()
    {
        LL x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
    void exgcd(LL a,LL b,LL &d,LL &x,LL& y)
    {
        if(!b)d=a,x=1,y=0;
        else exgcd(b,a%b,d,y,x),y-=x*(a/b);
    }
    LL inv(LL a,LL p)
    {
        LL d,x,y;exgcd(a,p,d,x,y);
        return (x+p)%p==0?p:(x+p)%p;
    }
    int main()
    {
        LL m1,m2,c1,c2;
        while(~scanf("%lld",&k))
        {
            for(int i=1;i<=k;i++)
                m[i]=read(),c[i]=read();
            for(int i=2;i<=k;i++)
            {
                m1=m[i-1],m2=m[i],c1=c[i-1],c2=c[i];
                LL t=gcd(m1,m2);
                if((c2-c1)%t!=0){c[k]=-1;break;}
                m[i]=m1*m2/t;
                c[i]=inv(m1/t,m2/t)*((c2-c1)/t)%(m2/t)*m1+c1;
                c[i]=(c[i]%m[i]+m[i])%m[i];
            }
            printf("%lld
    ",c[k]);
        }
        return 0;
    }
    View Code

    7.0 Lucas

    7.1 扩展Lucas

    其他

    1.0 高精度

  • 相关阅读:
    在Fedora10上安装MySQL5.0.18,告捷!
    直接修改class文件内容即使是文本会导致App异常,正确方式是修改java再用生成的class替换掉原有的class
    生命的真谛不在于你呼吸的次数,而在于那些令你无法呼吸的时刻
    开放Fedora10自带的MySQL5.0.67的对外数据库服务
    重装上了Fedora8自带的MySQL5.0.45,再试,告捷!!
    Shell程序荟萃
    程序的价值
    两条Find指令
    Linux防火墙配置
    在Foreda8上安装libaio-0.3.105-2.i386.rpm
  • 原文地址:https://www.cnblogs.com/Zars19/p/6716606.html
Copyright © 2011-2022 走看看