模板整理(持续更新)

这篇博客整理模板  便于自己使用

另外渐渐不爱写博客 就记录写关键的模板和题目 更新不会像以前那么频繁

一维并查集:

int findx(int x)  
{  
    int r=x;  
    while(pre[r]!=r)  
    {  
        r=pre[r];  
    }  
  
    int i=x;  
    int j;  
    while(pre[i]!=r)  
    {  
        j=pre[i];  
        pre[i]=r;  
        i=j;  
    }  
    return r;  
}  
  
int join(int x,int y)  
{  
    int p1=findx(x);  
    int p2=findx(y);  
    if(p1!=p2)  
    {  
        pre[p2]=p1;  
    }  
}  

二维并查集:

struct xjy  
{  
    int x;  
    int y;  
};  
int dir[4][2]={1,0,0,1,-1,0,0,-1};  
char mmap[1111][1111];  
xjy pre[1111][1111];  
int num[1111][1111];  
xjy findx(xjy xx)  
{  
    xjy r=xx;  
    while(pre[r.x][r.y].x!=r.x||pre[r.x][r.y].y!=r.y)  
        {  
            r=pre[r.x][r.y];  
        }  
  
    xjy i=xx,j;  
    while(pre[i.x][i.y].x!=r.x||pre[i.x][i.y].y!=r.y)  
    {  
        j=pre[i.x][i.y];  
        pre[i.x][i.y]=r;  
        i=j;  
    }  
    return r;  
}  
void join (xjy xx,xjy yy)  
{  
    xjy p1=findx(xx);  
    xjy p2=findx(yy);  
    if(p1.x!=p2.x||p1.y!=p2.y)  
        {  
            pre[p1.x][p1.y]=p2;  
            num[p2.x][p2.y]+=num[p1.x][p1.y];  
            num[p1.x][p1.y]=0;  
        }  
}  


带权并查集:

#include <iostream>  
#include <queue>  
#include <stdio.h>  
#include <stdlib.h>  
#include <stack>  
#include <limits.h>  
#include <string>  
#include <string.h>  
#include <vector>  
#include <set>  
#include <map>  
#include <algorithm>  
#include <math.h>  
using namespace std;  
#define maxn 100100  
int pre[maxn*3+10];  
int findx(int x)  
{  
    int r=x;  
    while(pre[r]!=r)  
    {  
        r=pre[r];  
    }  
  
    int i=x;  
    int j;  
    while(pre[i]!=r)  
    {  
        j=pre[i];  
        pre[i]=r;  
        i=j;  
    }  
    return r;  
}  
  
void join(int x,int y)  
{  
    int p1=findx(x);  
    int p2=findx(y);  
    if(p1!=p2)  
    {  
        pre[p2]=p1;  
    }  
}  
  
int judge(int x,int y)  
{  
    int p1=findx(x);  
    int p2=findx(y);  
    if(p1==p2)  
        return 1;  
    return 0;  
}  
int main()  
{  
    int t;  
    cin >> t;  
    while(t--)  
    {  
        for(int i=1;i<maxn*3;i++)  
            pre[i]=i;  
        int n,m;  
        cin >> n >> m;  
        for(int i=1;i<=m;i++)  
        {  
            char c;  
            int x,y;  
            scanf(" %c %d%d",&c,&x,&y);  
            if(c=='D')  
            {  
                join(x,y+n);  
                join(x+n,y);  
            }  
            else  
            {  
                if(judge(x,y+n)||judge(x+n,y))  
                    printf("In different gangs.\n");  
                else if(judge(x,y)||judge(x+n,y+n))  
                    printf("In the same gang.\n");  
                else  
                    printf("Not sure yet.\n");  
            }  
        }  
    }  
}  

一维树状数组

扫描二维码关注公众号,回复: 2484874 查看本文章
int lowbit (int x)  
{  
    return x&-x;  
}  
int getsum(int x)  
{  
    int sum=0;  
    while(x>0)  
    {  
        sum+=tree[x];  
        x-=lowbit(x);  
    }  
    return sum;  
}  
void add(int x,int num)  
{  
    while(x<1000000)  
    {  
        tree[x]+=num;  
        x+=lowbit(x);  
    }  
}  

二维树状数组:

#include <bits/stdc++.h>  
using namespace std;  
int tree[1111][1111];  
int book[1111][1111];  
int lowbit (int x)  
{  
    return x&-x;  
}  
int getsum(int x,int y)  
{  
    int sum=0;  
    for(int i=x;i>0;i-=lowbit(i))  
        for(int j=y;j>0;j-=lowbit(j))  
            sum+=tree[i][j];  
    return sum;  
}  
void add(int x,int y,int num)  
{  
  
        for(int i=x;i<=1000;i+=lowbit(i))  
            for(int j=y;j<=1000;j+=lowbit(j))  
                tree[i][j]+=num;  
        book[x][y]+=num;  
}  


线段树改查 dfs序:

#include <iostream>  
#include <queue>  
#include <stdio.h>  
#include <stdlib.h>  
#include <stack>  
#include <limits>  
#include <string>  
#include <string.h>  
#include <vector>  
#include <set>  
#include <map>  
#include <algorithm>  
#include <math.h>  
using namespace std;  
#define maxn 100000+5  
int flag;  
struct xjy  
{  
    int left;  
    int right;  
    int num;  
    int target;  
    int lazy;  
    int sum;  
    int time;  
};  
xjy tree[maxn<<2];  
vector<int > point[maxn];  
int a[maxn],l[maxn],r[maxn];  
int ans=0;  
int cnt=1;  
int remember[maxn];  
int n,m;  
int t;  
void show(int i,int left,int right)  
{  
   if(left==right)  
    {  
        printf("%d %d %d %d %d %d\n",tree[i].sum,tree[i].left,tree[i].right,tree[i].lazy,tree[i].target,tree[i].time);  
        return;  
    }  
    int mid=(left+right)>>1;  
    show(i<<1,left,mid);  
    show(i<<1|1,mid+1,right);  
    printf("%d %d %d %d %d %d\n",tree[i].sum,tree[i].left,tree[i].right,tree[i].lazy,tree[i].target,tree[i].time);  
}  
int ccnt=0;  
void dfs(int i)  
{  
    ccnt++;  
    l[i]=ccnt;  
    for(int ii=0;ii<point[i].size();ii++)  
        {  
            dfs(point[i][ii]);  
        }  
    r[i]=ccnt;  
}  
void build(int i,int left,int right)  
{  
    if(left==right)  
    {  
        tree[i].sum=-1;  
        tree[i].left=left;  
        tree[i].right=right;  
        return;  
    }  
    int mid=(left+right)>>1;  
    build(i<<1,left,mid);  
    build(i<<1|1,mid+1,right);  
    tree[i].sum=-1;  
    tree[i].left=left;  
    tree[i].right=right;  
}  
void updateregion(int i,int left,int right,int ffind,int val)  
{  
    if(tree[i].lazy)  
    {  
        tree[i].lazy=0;  
        if(tree[i<<1].time<tree[i].time)  
            {  
                tree[i<<1].lazy=1;  
                tree[i<<1].target=tree[i].target;  
                tree[i<<1].time=tree[i].time;  
            }  
        if(tree[i<<1|1].time<tree[i].time)  
            {  
                tree[i<<1|1].lazy=1;  
                tree[i<<1|1].target=tree[i].target;  
                tree[i<<1|1].time=tree[i].time;  
            }  
        tree[i].sum=tree[i].target;  
        tree[i].target=tree[i].time=0;  
    }  
    if(tree[i].left==left&&tree[i].right==right)  
    {  
        tree[i].lazy=1;  
        tree[i].target=val;  
        tree[i].time=cnt;  
        return;  
    }  
      
    int mid=(tree[i].left+tree[i].right)>>1;  
    if(right<=mid)  
        updateregion(i<<1,left,right,ffind,val);  
    else if(left>mid)  
        updateregion(i<<1|1,left,right,ffind,val);  
    else  
    {  
        updateregion(i<<1,left,mid,ffind,val);  
        updateregion(i<<1|1,mid+1,right,ffind,val);  
    }  
}  
int queryregion(int i,int ffind,int left,int right)  
{  
    if(tree[i].lazy)  
    {  
        tree[i].lazy=0;  
        if(tree[i<<1].time<tree[i].time)  
            {  
                tree[i<<1].lazy=1;  
                tree[i<<1].target=tree[i].target;  
                tree[i<<1].time=tree[i].time;  
            }  
        if(tree[i<<1|1].time<tree[i].time)  
            {  
                tree[i<<1|1].lazy=1;  
                tree[i<<1|1].target=tree[i].target;  
                tree[i<<1|1].time=tree[i].time;  
            }  
        tree[i].sum=tree[i].target;  
        tree[i].target=tree[i].time=0;  
    }  
    if(tree[i].left==left&&tree[i].right==right)  
    {  
        //show(1,1,n);  
        return tree[i].sum;  
    }  
    int mid=(tree[i].left+tree[i].right)>>1;  
    if(right<=mid)  
        return queryregion(i<<1,ffind,left,right);  
    else if(left>mid)  
        return queryregion(i<<1|1,ffind,left,right);  
    else  
    {  
        return queryregion(i<<1,ffind,left,mid);  
        return queryregion(i<<1|1,ffind,mid+1,right);  
    }  
}  

扫描线:

#include <bits/stdc++.h>  
using namespace std;  
#define maxn 2005  
struct Line  
{  
    double x;  
    double yleft,yright;  
    int flag;  
};  
struct xjy  
{  
    int left,right;  
    double yleft,yright;  
    int cnt;  
    double once;  
    double twice;  
};  
xjy tree[maxn<<2];  
Line line[maxn];  
double Hash[maxn];  
bool cmp(Line a,Line b)  
{  
    return a.x<b.x;  
}  
void build(int i,int left,int right)  
{  
    tree[i].left=left;  
    tree[i].right=right;  
    tree[i].once=0;  
    tree[i].twice=0;  
    tree[i].yleft=Hash[left];  
    tree[i].yright=Hash[right];  
    if(left+1==right)  
        return ;  
    int mid=(left+right)>>1;  
    build(i<<1,left,mid);  
    build(i<<1|1,mid,right);  
}  
void check(int i)  
{  
    if(tree[i].cnt>=2)  
    {  
        tree[i].once=tree[i].yright-tree[i].yleft;  
        tree[i].twice=tree[i].yright-tree[i].yleft;  
        return ;  
    }  
    else if(tree[i].cnt==1)  
    {  
        tree[i].once=tree[i].yright-tree[i].yleft;  
        if(tree[i].left+1==tree[i].right)  
            tree[i].twice=0;  
        else  
            tree[i].twice=tree[i<<1].once+tree[i<<1|1].once;  
    }  
    else  
    {  
        if(tree[i].left+1==tree[i].right)  
            tree[i].once=tree[i].twice=0;  
        else  
            {  
                tree[i].once=tree[i<<1].once+tree[i<<1|1].once;  
                tree[i].twice=tree[i<<1].twice+tree[i<<1|1].twice;  
            }  
    }  
}  
  
void update(int i,Line a)  
{  
    if(a.yleft==tree[i].yleft&&tree[i].yright==a.yright)  
    {  
        tree[i].cnt+=a.flag;  
        check(i);  
        //cout << tree[i].left << tree[i].right << endl;  
        return;  
    }  
    if(a.yright<=tree[i<<1].yright)  
        update(i<<1,a);  
    else if(a.yleft>=tree[i<<1|1].yleft)  
        update(i<<1|1,a);  
    else  
    {  
        Line temp=a;  
        temp.yright=tree[i<<1].yright;  
        update(i<<1,temp);  
        temp=a;  
        temp.yleft=tree[i<<1|1].yleft;  
        update(i<<1|1,temp);  
    }  
    check(i);  
    //cout << tree[i].left << tree[i].right <<endl;  
}  
  
int main()  
{  
    int t;  
    scanf("%d",&t);  
    for(int step=1;step<=t;step++)  
    {  
        int n;int cnt=1;  
        scanf("%d",&n);  
        for(int i=1;i<=n;i++)  
        {  
            double x1,x2,y1,y2;  
            scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);  
            line[cnt].yleft=y1;  
            line[cnt].yright=y2;  
            line[cnt].x=x1;  
            line[cnt].flag=1;  
            Hash[cnt++]=y1;  
  
            line[cnt].yleft=y1;  
            line[cnt].yright=y2;  
            line[cnt].x=x2;  
            line[cnt].flag=-1;  
            Hash[cnt++]=y2;  
        }  
        sort(line+1,line+cnt,cmp);  
        sort(Hash+1,Hash+cnt);  
        build(1,1,cnt-1);  
        double ans=0;  
        update(1,line[1]);  
        for(int i=2;i<cnt;i++)  
        {  
            ans+=tree[1].twice*(line[i].x-line[i-1].x);  
            update(1,line[i]);  
        }  
        printf("%.2lf\n",ans);  
    }  
}  

主席树:

#include <queue>  
#include <stdio.h>  
#include <map>  
#include <string>  
#include <iostream>  
#include <string.h>  
#include <stack>  
#include <algorithm>  
#include <set>  
using namespace std;  
#define maxn 100010  
struct xjy  
{  
    int left;  
    int right;  
    int num;  
};  
struct xxjy  
{  
    int num;  
    int id;  
    bool operator < (const xxjy &r)const  
    {  
        return num<r.num;  
    }  
};  
xjy tree[maxn*20];  
int T[maxn];  
xxjy a[maxn];  
int tot;  
int n,m;  
int build(int left,int right)  
{  
    int root=tot++;  
    if(left==right)  
    {  
        tree[root].num=0;  
        tree[root].left=tree[root].right=0;  
        return root;  
    }  
    int mid=(left+right)>>1;  
    tree[root].left=build(left,mid);  
    tree[root].right=build(mid+1,right);  
    tree[root].num=0;  
    return root;  
}  
  
int update(int root,int pos,int val)  
{  
    int now=tot++;  
    int tmp=now;  
    tree[now].num=tree[root].num+val;  
    int left=1;  
    int right=n;  
    while(left<right)  
    {  
        int mid=(left+right)>>1;  
        if(pos<=mid)  
        {  
            tree[now].left=tot++;  
            tree[now].right=tree[root].right;  
            root=tree[root].left;  
            now=tree[now].left;  
            right=mid;  
        }  
        else  
        {  
            tree[now].left=tree[root].left;  
            tree[now].right=tot++;  
            root=tree[root].right;  
            now=tree[now].right;  
            left=mid+1;  
        }  
        tree[now].num=tree[root].num+val;  
    }  
    return tmp;  
}  
int ans;  
void query(int root,int left,int right,int l,int r)  
{  
    if(left==l&&right==r)  
    {  
        ans+=tree[root].num;  
        return;  
    }  
    int mid=(l+r)>>1;  
    if(right<=mid)  
    {  
        query(tree[root].left,left,right,l,mid);  
    }  
    else if(left>mid)  
    {  
        query(tree[root].right,left,right,mid+1,r);  
    }  
    else  
    {  
        query(tree[root].left,left,mid,l,mid);  
        query(tree[root].right,mid+1,right,mid+1,r);  
    }  
}  
int main()  
{  
    int t;  
    scanf("%d",&t);  
    for(int cnt=1;cnt<=t;cnt++)  
    {  
        printf("Case %d:\n",cnt);  
        tot=0;  
        scanf("%d%d",&n,&m);  
        T[0]=build(1,n);  
        for(int i=1;i<=n;i++)  
            scanf("%d",&a[i].num),a[i].id=i;  
        sort(a+1,a+n+1);  
        for(int i=1;i<=n;i++)  
            {  
                T[i]=update(T[i-1],a[i].id,1);  
            }  
        for(int i=1;i<=m;i++)  
        {  
            int l,r,mid;  
            scanf("%d%d%d",&l,&r,&mid);  
            xxjy midmid;  
            midmid.num=mid;  
            midmid.id=n+1;  
            int time=upper_bound(a+1,a+n+1,midmid)-a-1;  
            ans=0;  
            query(T[time],l+1,r+1,1,n);  
            printf("%d\n",ans);  
        }  
  
    }  
}  
区间合并

#include <iostream>  
#include <queue>  
#include <stdio.h>  
#include <stdlib.h>  
#include <stack>  
#include <limits>  
#include <string>  
#include <string.h>  
#include <vector>  
#include <set>  
#include <map>  
#include <algorithm>  
#include <math.h>  
using namespace std;  
#define maxn 60010  
struct xjy  
{  
    int left;  
    int right;  
    int lmax;  
    int rmax;  
    int mmax;  
};  
xjy tree[maxn<<2];  
int a[maxn];  
int ans=0;  
  
void build(int i,int left ,int right)  
{  
  
    {  
        tree[i].left=left;  
        tree[i].right=right;  
        tree[i].lmax=tree[i].rmax=tree[i].mmax=right-left+1;  
    }  
    if(left!=right)  
    {  
        int mid=(left+right)>>1;  
        build(i<<1,left,mid);  
        build (i<<1|1,mid+1,right);  
    }  
}  
  
void updateregion(int i,int left,int right,int val)  
{  
    if(tree[i].left==left&&tree[i].right==right)  
    {  
        tree[i].lmax=tree[i].rmax=tree[i].mmax=val;  
        return;  
    }  
    int mid=(tree[i].left+tree[i].right)>>1;  
    if(right<=mid)  
        updateregion(i<<1,left,right,val);  
    else if(left>mid)  
        updateregion(i<<1|1,left,right,val);  
    else  
    {  
        updateregion(i<<1,left,mid,val);  
        updateregion(i<<1|1,mid+1,right,val);  
    }  
    tree[i].lmax=tree[i<<1].lmax;  
    tree[i].rmax=tree[i<<1|1].rmax;  
    tree[i].mmax=max(max(tree[i<<1].mmax,tree[i<<1|1].mmax),tree[i<<1].rmax+tree[i<<1|1].lmax);  
    if(tree[i<<1].lmax==(tree[i<<1].right-tree[i<<1].left+1))  
        tree[i].lmax+=tree[i<<1|1].lmax;  
    if(tree[i<<1|1].rmax==(tree[i<<1|1].right-tree[i<<1|1].left+1))  
        tree[i].rmax+=tree[i<<1].rmax;  
}  
  
int query(int i,int t)  
{  
    if(tree[i].left==tree[i].right||tree[i].mmax==(tree[i].right-tree[i].left+1)||!tree[i].mmax)  
    {  
        return tree[i].mmax;  
    }  
    int mid=(tree[i].left+tree[i].right)>>1;  
    if(t<=mid)  
    {  
        if(t>=tree[i<<1].right-tree[i<<1].rmax+1)  
            return query(i<<1,t)+query(i<<1|1,mid+1);  
        else  
            return query(i<<1,t);  
    }  
    else  
    {  
        if(t<=tree[i<<1|1].left+tree[i<<1|1].lmax-1)  
            return query(i<<1|1,t)+query(i<<1,mid);  
        else  
            return query(i<<1|1,t);  
    }  
}  
  
int main()  
{  
    int n,m;  
    int t;  
    while(~scanf("%d%d",&n,&m))  
    {  
        for(int i=0;i<maxn;i++)  
        {  
            tree[i].left=0;  
            tree[i].lmax=0;  
            tree[i].mmax=0;  
            tree[i].right=0;  
            tree[i].rmax=0;  
        }  
        build(1,1,n);  
        stack<int > ss;  
        for(int i=1;i<=m;i++)  
        {  
            char s;  
            scanf(" %c",&s);  
            if(s=='D')  
            {  
                int mid;  
                scanf("%d",&mid);  
                updateregion(1,mid,mid,0);  
                ss.push(mid);  
                //show(1,1,n);  
                //printf("\n");  
            }  
            else if(s=='R')  
            {  
                int mid;  
                mid=ss.top();  
                ss.pop();  
                updateregion(1,mid,mid,1);  
                //show(1,1,10);  
            }  
            else  
            {  
                int mid;  
                scanf("%d",&mid);  
                ans=0;  
                printf("%d\n",query(1,mid));  
            }  
        }  
    }  
}  

树的遍历转化:

#include <iostream>  
#include <queue>  
#include <stdio.h>  
#include <stdlib.h>  
#include <stack>  
#include <limits>  
#include <string>  
#include <string.h>  
#include <vector>  
#include <set>  
#include <map>  
#include <algorithm>  
#include <math.h>  
using namespace std;  
int n=0;  
struct tree  
{  
    int val;  
    struct tree* l;  
    struct tree* r;  
};  
vector<int > pre;  
vector<int > in;  
int ii=0;  
tree * after(int l,int r)  
{  
    if(l>=r)  
        return NULL;  
    tree *mid = new tree;  
    mid->val=pre[ii++];  
    int m=(find(in.begin(),in.end(),mid->val)-in.begin());  
    mid->l=after(l,m);  
    mid->r=after(m+1,r);  
    return mid;  
}  
void show(tree* root)  
{  
    if(root==NULL)  
        return ;  
    show(root->l);  
    show(root->r);  
    printf("%d ",root->val);  
}  
int main()  
{  
    int n,k;  
    while(cin >> n)  
    {  
        for(int i=0;i<n;i++)  
        {  
            cin >> k;  
            in.push_back(k);  
        }  
        for(int i=0;i<n;i++)  
        {  
            cin >> k;  
            pre.push_back(k);  
        }  
        tree* root=after(0,n);  
        show(root);  
        cout << endl;  
    }  
}  

最短路:

struct xjy  
{  
    int from;  
    int to;  
    int dis;  
    bool operator < (const xjy &r)const  
    {  
        return dis>r.dis;  
    }  
};  
vector <xjy > mmap[1000001];  
vector<xjy> remember;  
int dis[1000001];  
int book[1000001];  
int sum,q,p;  
void dijkstra(int begin)  
{  
    for(int i=0;i<1000000;i++)  
    {  
        dis[i]=INT_MAX;  
        book[i]=0;  
    }  
    priority_queue<xjy> q;  
    xjy mid;  
    mid.from=1;  
    mid.dis=0;  
    q.push(mid);  
    while(!q.empty())  
    {  
        mid=q.top();  
        q.pop();  
        if(book[mid.from])  
            continue;  
        for(int i=0;i<mmap[mid.from].size();i++)  
        {  
            if(!book[mmap[mid.from][i].to]&&dis[mmap[mid.from][i].to]>mid.dis+mmap[mid.from][i].dis)  
            {  
                book[mmap[mid.from][i].from]=1;  
                dis[mmap[mid.from][i].to]=mid.dis+mmap[mid.from][i].dis;  
                xjy midmid;  
                midmid.from=mmap[mid.from][i].to;  
                midmid.dis=dis[mmap[mid.from][i].to];  
                q.push(midmid);  
            }  
        }  
    }  
    for(int i=0;i<=p;i++)  
    {  
        if(dis[i]!=INT_MAX)  
        {  
            sum+=dis[i];  
            //cout << dis[i] <<" ";  
        }  
    }  
}  

kmp:

#include <string>  
#include <iostream>  
#include <stdio.h>  
#include <vector>  
#include <string.h>  
#include <algorithm>  
using namespace std;  
int nnext[111];  
char ss[111][111];  
char mmid[111];  
void getnext()  
{  
    int i=0;  
    int j=-1;  
    nnext[0]=-1;  
    int len=strlen(mmid);  
    while(i<len)  
    {  
        if(j==-1||mmid[i]==mmid[j])  
        {  
            i++;  
            j++;  
            nnext[i]=j;  
        }  
        else  
            j=nnext[j];  
    }  
}  
int kmp(int s)  
{  
    int i=0;int j=0;  
    int len=strlen(ss[s]);  
    int lenn=strlen(mmid);  
    getnext();  
    while(i<len)  
    {  
        if(j==-1||ss[s][i]==mmid[j])  
        {  
            i++;  
            j++;  
        }  
        else  
            j=nnext[j];  
        if(j==lenn)  
            return 1;  
    }  
    return 0;  
}  

最大最小表示法

最小:

[cpp]  view plain  copy
  1. int getmin()  
  2. {  
  3.     int i=0,j=1,k=0;  
  4.     while(i<len&&j<len&&k<len)  
  5.     {  
  6.         if(s[(i+k)%len]==s[(j+k)%len])  
  7.             k++;  
  8.         else  
  9.         {  
  10.             if(s[(i+k)%len]>s[(j+k)%len])  
  11.                 i+=k+1;  
  12.             else  
  13.                 j+=k+1;  
  14.             if(i==j)  
  15.                 j++;  
  16.             k=0;  
  17.         }  
  18.     }  
  19.     return min(i,j);  
  20. }  
最大;
[cpp]  view plain  copy
  1. int getmax()  
  2. {  
  3.     int i=0,j=1,k=0;  
  4.     while(i<len&&j<len&&k<len)  
  5.     {  
  6.         if(s[(i+k)%len]==s[(j+k)%len])  
  7.             k++;  
  8.         else  
  9.         {  
  10.             if(s[(i+k)%len]>s[(j+k)%len])  
  11.                 j+=k+1;  
  12.             else  
  13.                 i+=k+1;  
  14.             if(i==j)  
  15.                 j++;  
  16.             k=0;  
  17.         }  
  18.     }  
  19.     return min(i,j);  
  20. }  
后缀数组+rmq:

#include <stdio.h>  
#include <algorithm>  
#include <iostream>  
#include <string.h>  
#include <math.h>  
using namespace std;  
#define maxn 22222  
int n;  
char s[maxn];  
int c[maxn],sa[maxn],x[maxn],y[maxn],height[maxn],rrank[maxn],st[maxn][20];  
void SA(int m)  
{  
    for(int i=0;i<m;i++)  
        c[i]=0;  
    for(int i=0;i<n;i++)  
        c[x[i]=s[i]]++;  
    for(int i=1;i<m;i++)  
        c[i]+=c[i-1];  
    for(int i=n-1;i>=0;i--)  
        sa[--c[x[i]]]=i;  
    for(int k=1;k<=n;k<<=1)  
    {  
        int p=0;  
        for(int i=n-k;i<n;i++)  
            y[p++]=i;  
        for(int i=0;i<n;i++)  
            if(sa[i]>=k)  
                y[p++]=sa[i]-k;  
        for(int i=0;i<m;i++)  
            c[i]=0;  
        for(int i=0;i<n;i++)  
            c[x[y[i]]]++;  
        for(int i=1;i<m;i++)  
            c[i]+=c[i-1];  
        for(int i=n-1;i>=0;i--)  
            sa[--c[x[y[i]]]]=y[i];  
        swap(x,y);  
        p=1;  
        x[sa[0]]=0;  
        for(int i=1;i<n;i++)  
            x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;  
        if(p>=n)  
            break;  
        m=p;  
    }  
}  
void getheight()  
{  
    int k=0;  
    for(int i=0;i<=n;i++)  
        rrank[sa[i]]=i;  
    for(int i=0;i<n;i++)  
    {  
        if(k)  
            k--;  
        int j=sa[rrank[i]-1];  
        while(s[i+k]==s[j+k])  
            k++;  
        height[rrank[i]]=k;  
    }  
}  
void ST()  
{  
    for(int i=1;i<=n;i++)  
        st[i][0]=height[i];  
    for(int j=1;j<=19;j++)  
        for(int i=1;i+(1<<j)-1<=n;i++)  
            st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);  
}  
int getmin(int x,int y)  
{  
    int l=rrank[x];  
    int r=rrank[y];  
    if(l>r)  
        swap(l,r);  
    l++;  
    int k=log2(r-l+1);  
    return min(st[l][k],st[r-(1<<k)+1][k]);  
}  


三分:

#include <bits/stdc++.h>  
using namespace std;  
#define eps 0.0000001  
struct xjy  
{  
    double x;  
    double y;  
    double vx;  
    double vy;  
};  
vector<xjy > point;  
int n;  
double dis(double t,int now1,int now2)  
{  
    return sqrt(((point[now1].x+point[now1].vx*t)-(point[now2].x+point[now2].vx*t))*  
                ((point[now1].x+point[now1].vx*t)-(point[now2].x+point[now2].vx*t))+  
                ((point[now1].y+point[now1].vy*t)-(point[now2].y+point[now2].vy*t))*  
                ((point[now1].y+point[now1].vy*t)-(point[now2].y+point[now2].vy*t)));  
}  
double cal(double t)  
{  
    double ans=0;  
    for(int i=0;i<n;i++)  
        for(int j=i+1;j<n;j++)  
        {  
            ans=max(ans,dis(t,i,j));  
        }  
    return ans;  
}  
double sf()  
{  
    double l=0;  
    double r=1e8;  
    while((r-l)>=eps)  
    {  
        double mid1=(l*2+r)/3;  
        double mid2=(l+r*2)/3;  
        //cout << cal(mid2)-cal(mid1) <<endl;  
        if(cal(mid2)-cal(mid1)>eps)  
            r=mid2;  
        else  
            l=mid1;  
    }  
    return r;  
}  

二分图匹配:

#include<cstdio>  
#include<cstring>  
#include<iostream>  
#include<queue>  
#include<vector>  
#include<cmath>  
#include<algorithm>  
using namespace std;  
const int N=505;  
int line[N][N];  
int girl[N],used[N];  
int k,m,n;  
bool found(int x)  
{  
    for(int i=1; i<=n; i++)  
    {  
        if(line[x][i]&&!used[i])  
        {  
            used[i]=1;  
            if(girl[i]==0||found(girl[i]))  
            {  
                girl[i]=x;  
                return 1;  
            }  
        }  
    }  
    return 0;  
}  

点 线:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <set>
#include <string>
#include <math.h>

using namespace std;

const double eps = 1e-8;
int sgn(double x)
{
    if(fabs(x) < eps)return 0;
    if(x < 0)return -1;
    else return 1;
}
struct Point
{
    double x,y;
    Point(){}
    Point(double _x,double _y)
    {
        x = _x;y = _y;
    }
    Point operator -(const Point &b)const
    {
        return Point(x - b.x,y - b.y);
    }
    //叉积
    double operator ^(const Point &b)const
    {
        return x*b.y - y*b.x;
    }
    //点积
    double operator *(const Point &b)const
    {
        return x*b.x + y*b.y;
    }
    void input()
    {
        scanf("%lf%lf",&x,&y);
    }
};
struct Line
{
    Point s,e;
    Line(){}
    Line(Point _s,Point _e)
    {
        s = _s;e = _e;
    }
    //两直线相交求交点
    //第一个值为0表示直线重合,为1表示平行,为0表示相交,为2是相交
    //只有第一个值为2时,交点才有意义
    pair<int,Point> operator &(const Line &b)const
    {
        Point res = s;
        if(sgn((s-e)^(b.s-b.e)) == 0)
        {
            if(sgn((s-b.e)^(b.s-b.e)) == 0)
                return make_pair(0,res);//重合
            else return make_pair(1,res);//平行
        }
        double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
        res.x += (e.x-s.x)*t;
        res.y += (e.y-s.y)*t;
        return make_pair(2,res);
    }
};
//判断直线和线段相交
bool Seg_inter_line(Line l1,Line l2) //判断直线l1和线段l2是否相交
{
    return sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0;
}

字典树

#include <iostream>
#include <string>
#include <vector>
#include <stdio.h>
#include <string.h>
using namespace std;
#define maxn 4000010
int tot;
int n;
int trie[maxn][26];
int sum[maxn];
char s[33];
void update(int root)
{
    for(int i=0;s[i];i++)
    {
        int mid=s[i]-'a';
        if(trie[root][mid]==0)
        {
            trie[root][mid]=++tot;
        }
        sum[trie[root][mid]]++;
        root=trie[root][mid];
    }
}
int query(int root)
{
    int mid;
    int len=strlen(s);
    for(int i=0;i<len;i++)
    {
        mid=s[i]-'a';
        if(trie[root][mid]==0)
            return 0;
        root=trie[root][mid];
    }
    return sum[root];
}


猜你喜欢

转载自blog.csdn.net/xuejye/article/details/79587061