模板NeverGiveUpNeverSurrenderTerribleTerribleDamage-PowerOverwhelming

NGUNSTTD-PO

Name: NeverGiveUpNeverSurrenderTerribleTerribleDamage-PowerOverwhelming

Usage: Put it before main function

Tags: 头文件 循环 常用语句

/** head-file **/

#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <set>
#include <map>
#include <algorithm>

/** define-for **/

#define REP(i, n) for (int i=0;i<int(n);++i)
#define FOR(i, a, b) for (int i=int(a);i<int(b);++i)
#define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)
#define REP_1(i, n) for (int i=1;i<=int(n);++i)
#define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i)
#define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i)
#define REP_N(i, n) for (i=0;i<int(n);++i)
#define FOR_N(i, a, b) for (i=int(a);i<int(b);++i)
#define DWN_N(i, b, a) for (i=int(b-1);i>=int(a);--i)
#define REP_1_N(i, n) for (i=1;i<=int(n);++i)
#define FOR_1_N(i, a, b) for (i=int(a);i<=int(b);++i)
#define DWN_1_N(i, b, a) for (i=int(b);i>=int(a);--i)

/** define-useful **/

#define clr(x,a) memset(x,a,sizeof(x))
#define sz(x) int(x.size())
#define see(x) cerr<<#x<<" "<<x<<endl
#define se(x) cerr<<" "<<x
#define pb push_back
#define mp make_pair

/** test **/

#define Display(A, n, m) {                      \
    REP(i, n){                                  \
        REP(j, m) cout << A[i][j] << " ";       \
        cout << endl;                           \
    }                                           \
}

#define Display_1(A, n, m) {                    \
    REP_1(i, n){                                \
        REP_1(j, m) cout << A[i][j] << " ";     \
        cout << endl;                           \
    }                                           \
}

using namespace std;

/** typedef **/

typedef long long LL;

/** Add - On **/

const int direct4[4][2]={ {0,1},{1,0},{0,-1},{-1,0} };
const int direct8[8][2]={ {0,1},{1,0},{0,-1},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1} };
const int direct3[6][3]={ {1,0,0},{0,1,0},{0,0,1},{-1,0,0},{0,-1,0},{0,0,-1} };

const int MOD = 1000000007;
const int INF = 0x3f3f3f3f;
const long long INFF = 1LL << 60;
const double EPS = 1e-9;
const double OO = 1e15;
const double PI = acos(-1.0); //M_PI;



/** head-file **/

#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
         #include 
        
          #include 
         
           #include 
          
            #include 
           
             #include 
            
              #include 
             
               #include 
              
                #include 
               
                 #include 
                 #include 
                 
                   /** define-for **/ #define REP(i, n) for (int i=0;i 
                  
                    =int(a);--i) #define REP_1(i, n) for (int i=1;i<=int(n);++i) #define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i) #define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i) #define REP_N(i, n) for (i=0;i 
                   
                     =int(a);--i) #define REP_1_N(i, n) for (i=1;i<=int(n);++i) #define FOR_1_N(i, a, b) for (i=int(a);i<=int(b);++i) #define DWN_1_N(i, b, a) for (i=int(b);i>=int(a);--i) /** define-useful **/ #define clr(x,a) memset(x,a,sizeof(x)) #define sz(x) int(x.size()) #define see(x) cerr<<#x<<" "< 
                    
                      < 
                     
                       << 60; const double EPS = 1e-9; const double OO = 1e15; const double PI = acos(-1.0); //M_PI; 
                      
                     
                    
                   
                  
                
               
              
             
            
           
          
         
       
      
      
     
     
    
    
   
   

//图论模板

const int maxn=111111;
const int maxm=511111;
int n,m;

struct EDGENODE{
    int to;
    int w;
    int next;
};
struct SGRAPH{
    int head[maxn];
    EDGENODE edges[maxm];
    int edge;
    int node;
    void init(int n)
    {
        clr(head,-1);
        node=n;
        edge=0;
    }
    void addedge(int u,int v,int c=0)
    {
        edges[edge].w=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
        edges[edge].w=c,edges[edge].to=u,edges[edge].next=head[v],head[v]=edge++;
    }
}graph;

最大流模板

const int INF = 0x3f3f3f3f;
const int maxm=11111;
const int maxn=2222;

struct edgenode
{
    int to,flow,next;
};

struct Dinic
{
    int node,src,dest,edge;
    int head[maxn],work[maxn],dis[maxn],q[maxn];
    edgenode edges[maxm];

    void prepare(int _node,int _src,int _dest)
    {
        node=_node,src=_src,dest=_dest;
        for (int i=0; i<node; i++) head[i]=-1;
        edge=0;
    }

    void addedge(int u,int v,int c)
    {
        edges[edge].flow=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
        edges[edge].flow=0,edges[edge].to=u,edges[edge].next=head[v],head[v]=edge++;
    }

    bool Dinic_bfs()
    {
        int i,u,v,l,r=0;
        for (i=0; i<node; i++) dis[i]=-1;
        dis[q[r++]=src]=0;
        for (l=0; l<r; l++){
            for (i=head[u=q[l]]; i!=-1; i=edges[i].next){
                if (edges[i].flow&&dis[v=edges[i].to]<0){
                    dis[q[r++]=v]=dis[u]+1;
                    if (v==dest) return true;
                }
            }
        }
        return false;
    }

    int Dinic_dfs(int u,int exp)
    {
        if (u==dest) return exp;
        for (int &i=work[u],v,tmp; i!=-1; i=edges[i].next){
            if (edges[i].flow&&dis[v=edges[i].to]==dis[u]+1&&
                (tmp=Dinic_dfs(v,min(exp,edges[i].flow)))>0){
                edges[i].flow-=tmp;
                edges[i^1].flow+=tmp;
                return tmp;
            }
        }
        return 0;
    }

    int Dinic_flow()
    {
        int i,ret=0,delta;
        while (Dinic_bfs()){
            for (i=0; i<node; i++) work[i]=head[i];
            while ( delta=Dinic_dfs(src,INF) ) ret+=delta;
        }
        return ret;
    }

}solver;

强连通分量模板

const int maxn=111111;
const int maxm=511111;
int n,m;

struct EDGENODE{
    int to;
    int w;
    int next;
};
struct SGRAPH{
    int head[maxn];
    EDGENODE edges[maxm];
    int edge;
    void init(int n)
    {
        clr(head,-1);
        edge=0;
    }
    void addedge(int u,int v,int c=0)
    {
        edges[edge].w=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
    }
    int pre[maxn],lowlink[maxn],sccno[maxn],scc_cnt,dfs_clock;
    stack<int>stk;
    void dfs(int u)
    {
        pre[u]=lowlink[u]=++dfs_clock;
        stk.push(u);
        for (int i=head[u];i!=-1;i=edges[i].next){
            int v=edges[i].to;
            if (!pre[v]){
                dfs(v);
                lowlink[u]=min(lowlink[u],lowlink[v]);
            } else if (!sccno[v]){
                lowlink[u]=min(lowlink[u],pre[v]);
            }
        }
        if (lowlink[u]==pre[u]){
            scc_cnt++;
            int x;
            do{
                x=stk.top();
                stk.pop();
                sccno[x]=scc_cnt;
            }while (x!=u);
        }
    }
    void find_scc(int n)
    {
        dfs_clock=scc_cnt=0;
        clr(sccno,0);
        clr(pre,0);
        while (!stk.empty()) stk.pop();
        REP(i,n) if (!pre[i]) dfs(i);
    }
}solver;


双连通模板

const int maxn=1111;
const int maxm=5111;
int n,m;

struct EDGENODE{
    int to;
    int w;
    bool cut;
    int next;
};
struct SEDGE{
    int u;
    int v;
    SEDGE(int uu=0,int vv=0){u=uu;v=vv;}
};
struct BCC_GRAPH{
    int head[maxn];
    EDGENODE edges[maxm];
    int edge;
    void init()
    {
        clr(head,-1);
        edge=0;
    }
    void addedge(int u,int v,int c=0)
    {
        edges[edge].cut=0,edges[edge].w=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
    }
    //BCC_Tarjan
    int dfn[maxn],low[maxn],bccno[maxn],dfs_clock,bcc_cnt;
    bool iscut[maxn];
    vector<int>bcc[maxn];
    stack<SEDGE>stk;
    int dfs(int u,int fa)
    {
        int lowu=dfn[u]=++dfs_clock;
        int child=0;
        for (int i=head[u];i!=-1;i=edges[i].next)
        {
            int v=edges[i].to;
            if (v==fa) continue;
            SEDGE e=SEDGE(u,v);
            if (!dfn[v])
            {
                stk.push(e);
                child++;
                int lowv=dfs(v,u);
                lowu=min(lowu,lowv);
                if (dfn[u]<=lowv) //cut 割点
                {
                    iscut[u]=true;
                    //done 点双连通
                    bcc_cnt++;
                    bcc[bcc_cnt].clear();
                    SEDGE x;
                    do{
                        x=stk.top();
                        stk.pop();
                        if (bccno[x.u]!=bcc_cnt)
                        {
                            bcc[bcc_cnt].push_back(x.u);
                            bccno[x.u]=bcc_cnt;
                        }
                        if (bccno[x.v]!=bcc_cnt)
                        {
                            bcc[bcc_cnt].push_back(x.v);
                            bccno[x.v]=bcc_cnt;
                        }
                    }while (x.u!=u||x.v!=v);
                    //over
                }
                if (dfn[u]<lowv)  //cut 桥
                {
                    edges[i].cut=true;
                    edges[i^1].cut=true;
                }
            }
            else if (dfn[v]<dfn[u])
            {
                stk.push(e);//done
                lowu=min(lowu,dfn[v]);
            }
        }
        if (fa<0&&child==1) iscut[u]=0;
        low[u]=lowu;
        return lowu;
    }
    void find_bcc(int n)
    {
        while (!stk.empty()) stk.pop();
        clr(dfn,0);
        clr(iscut,0);
        clr(bccno,0);
        dfs_clock=bcc_cnt=0;
        REP_1(i,n)
        {
            if (!dfn[i]) dfs(i,-1);
        }
    }
    //another
    int block[maxn];
    int vis[maxn];
    int b_num;
    void b_dfs(int u)
    {
        vis[u]=true;
        block[u]=b_num;
        for (int i=head[u];i!=-1;i=edges[i].next)
        {
            if (edges[i].cut) continue;
            int v=edges[i].to;
            if (!vis[v]) b_dfs(v);
        }
    }
    void find_block(int n)
    {
        //find_block 边双连通
        clr(block,0);
        clr(vis,0);
        b_num=0;
        REP_1(i,n)
        {
            if (!vis[i])
            {
                b_num++;
                b_dfs(i);
            }
        }
    }
}solver;

堆优化的dijkstra

const int maxn=11111;
const int maxm=1111111;

struct EdgeNode{
    int to;
    int w;
    int next;
};

struct HeapNode{
    int d,u;
    bool operator<(const HeapNode& rhs) const{
        return d>rhs.d;
    }
};

struct Dijkstra{
    EdgeNode edges[maxm];
    int head[maxn];
    int edge,n;
    void init(int n){
        this->n=n;
        memset(head,-1,sizeof(head));
        edge=0;
    }
    void addedges(int u,int v,int c){
        edges[edge].w=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
    }
    bool done[maxn];
    int dis[maxn];
    int pre[maxn];
    void dijkstra(int s){
        priority_queue<HeapNode>que;
        for (int i=0;i<n;i++) dis[i]=INF;
        dis[s]=0;
        memset(done,0,sizeof(done));
        que.push((HeapNode){0,s});
        while (!que.empty()){
            HeapNode x=que.top();
            que.pop();
            int u=x.u;
            if (done[u]) continue;
            done[u]=true;
            for (int i=head[u];i!=-1;i=edges[i].next){
                int v=edges[i].to;
                int w=edges[i].w;
                if (dis[v]>dis[u]+w){
                    dis[v]=dis[u]+w;
                    pre[v]=u;
                    que.push((HeapNode){dis[v],v});
                }
            }
        }
    }
}solver;

树堆Treap

#include <iostream>
#include <ctime>
 
#include <cstdlib>
#define MAX 100
 
using namespace std;
 
typedef struct
{
        int l,r,key,fix;
}node;
 
class treap
{
public:
        node p[MAX];
        int size,root;
        treap()
        {
                srand(time(0));
                size=-1;
                root=-1;
        }
 
        void rot_l(int &x)
        {
                int y=p[x].r;
                p[x].r=p[y].l;
                p[y].l=x;
                x=y;
        }
 
        void rot_r(int &x)
        {
                int y=p[x].l;
                p[x].l=p[y].r;
                p[y].r=x;
                x=y;
        }
 
        void insert(int &k,int tkey)
        {
                if (k==-1)
                {
                        k=++size;
                        p[k].l=p[k].r=-1;
                        p[k].key=tkey;
                        p[k].fix=rand();
                }
                else
                if (tkey<p[k].key)
                {
                        insert(p[k].l,tkey);
                        if (p[ p[k].l ].fix>p[k].fix)
                                rot_r(k);
                }
                else
                {
                        insert(p[k].r,tkey);
                        if (p[ p[k].r ].fix>p[k].fix)
                                rot_l(k);
                }
 
        }
 
        void remove(int &k,int tkey)
        {
                if (k==-1) return;
                if (tkey<p[k].key)
                        remove(p[k].l,tkey);
                else if (tkey>p[k].key)
                        remove(p[k].r,tkey);
                else
                {
                        if (p[k].l==-1 && p[k].r==-1)
                                k=-1;
                        else if (p[k].l==-1)
                                k=p[k].r;
                        else if (p[k].r==-1)
                                k=p[k].l;
                        else
                        if (p[ p[k].l ].fix < p[ p[k].r ].fix)
                        {
                                rot_l(k);
                                remove(p[k].l,tkey);
                        }
                        else
                        {
                                rot_r(k);
                                remove(p[k].r,tkey);
                        }
                }
        }
 
        void print(int k)
        {
                if (p[k].l!=-1)
                        print(p[k].l);
                cout << p[k].key << " : " << p[k].fix << endl;
                if (p[k].r!=-1)
                        print(p[k].r);
        }
};
 
treap T;
 
int main(void)
{
 
        int i;
        for (i = 3; i >= 1;i--)
                T.insert(T.root,i);
        T.print(T.root);
        for (i = 3; i >= 1;i--)
        {
                cout << endl;
                T.remove(T.root,i);
                T.print(T.root);
        }
        return 0;
}

伸展树Splay

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAX_N = 50000 + 10;
const int INF = ~0U >> 1;
struct Node {
	Node*ch[2], *p;
	int size, val, mx;
	int add;
	bool rev;
	Node() {
		size = 0;
		val = mx = -INF;
		add = 0;
	}
	bool d() {
		return this == p->ch[1];
	}
	void setc(Node*c, int d) {
		ch[d] = c;
		c->p = this;
	}
	void addIt(int ad) {
		add += ad;
		mx += ad;
		val += ad;
	}
	void revIt() {
		rev ^= 1;
	}
	void relax();
	void upd() {
		size = ch[0]->size + ch[1]->size + 1;
		mx = max(val, max(ch[0]->mx, ch[1]->mx));
	}
} Tnull, *null = &Tnull;
Node mem[MAX_N], *C = mem;

void Node::relax() {
	if (add != 0) {
		for (int i = 0; i < 2; ++i) {
			if (ch[i] != null)
				ch[i]->addIt(add);
		}
		add = 0;
	}
	if (rev) {
		swap(ch[0], ch[1]);
		for (int i = 0; i < 2; ++i) {
			if (ch[i] != null)
				ch[i]->revIt();
		}
		rev = 0;
	}
}

Node*make(int v) {
	C->ch[0] = C->ch[1] = null;
	C->size = 1;
	C->val = v;
	C->mx = v;
	C->add = 0;
	C->rev = 0;
	return C++;
}

Node*build(int l, int r) {
	if (l >= r)
		return null;
	int m = (l + r) >> 1;
	Node*t = make(0);
	t->setc(build(l, m), 0);
	t->setc(build(m + 1, r), 1);
	t->upd();
	return t;
}

Node*root;

Node*rot(Node*t) {
	Node*p = t->p;
	p->relax();
	t->relax();
	int d = t->d();
	p->p->setc(t, p->d());
	p->setc(t->ch[!d], d);
	t->setc(p, !d);
	p->upd();
	if (p == root)
		root = t;
}

void splay(Node*t, Node*f = null) {
	while (t->p != f) {
		if (t->p->p == f)
			rot(t);
		else
			t->d() == t->p->d() ? (rot(t->p), rot(t)) : (rot(t), rot(t));
	}
	t->upd();
}

Node* select(int k) {
	for (Node*t = root;;) {
		t->relax();
		int c = t->ch[0]->size;
		if (k == c)
			return t;
		if (k > c)
			k -= c + 1, t = t->ch[1];
		else
			t = t->ch[0];
	}
}

Node*&get(int l, int r) { //[l,r)
	Node*L = select(l - 1);
	Node*R = select(r);
	splay(L);
	splay(R, L);
	return R->ch[0];
}

int n, m;

int main() {
	cin >> n >> m;
	root = build(0, n + 2);
	root->p = null;
	for (int i = 0; i < m; ++i) {
		int k, l, r, v;
		scanf("%d%d%d", &k, &l, &r);
		Node*&t = get(l, r + 1);
		if (k == 1) {
			scanf("%d", &v);
			t->addIt(v);
			splay(t);
		} else if (k == 2) {
			t->revIt();
			splay(t);
		} else {
			printf("%d\n", t->mx);
		}
	}
}


TwoSAT模板

const int maxn=2111;
const int maxm=2111111;
int n,m;
struct EDGENODE{
    int to;
    int next;
};
struct TWO_SAT{
    int head[maxn*2];
    EDGENODE edges[maxm*2];
    int edge;
    int n;
    bool mark[maxn*2];
    int S[maxn*2],c;
    void init(int n){
        this->n=n;
        clr(mark,0);
        clr(head,-1);
        edge=0;
    }
    void addedge(int u,int v){
        edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
    }
    // x = xval or y = yval
    void add_clause(int x,int xval,int y,int yval){
        x=x*2+xval;
        y=y*2+yval;
        addedge(x^1,y);
        addedge(y^1,x);
    }
    void add_con(int x,int xval){
        x=x*2+xval;
        addedge(x^1,x);
    }
    bool dfs(int x){
        if (mark[x^1]) return false;
        if (mark[x]) return true;
        mark[x]=true;
        S[c++]=x;
        for (int i=head[x];i!=-1;i=edges[i].next)
            if (!dfs(edges[i].to)) return false;
        return true;
    }
    bool solve(){
        for (int i=0;i<n*2;i+=2)
            if (!mark[i]&&!mark[i+1]){
                c=0;
                if (!dfs(i)){
                    while (c>0) mark[S[--c]]=false;
                    if (!dfs(i+1)) return false;
                }
            }
        return true;
    }
}TwoSAT;

强连通Tarjan高效2-SAT


const int maxn=11111;
const int maxm=2111111;
int n,m;
struct EDGENODE{
    int to;
    int next;
};
struct TWO_SAT{
    int head[maxn*2];
    EDGENODE edges[maxm*2];
    int edge;
    int n;
    void init(int n){
        this->n=2*n;
        clr(head,-1);
        edge=0;
    }
    void addedge(int u,int v){
        edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
    }
    // x = xval or y = yval
    void add_clause(int x,int xval,int y,int yval){
        x=x*2+xval;
        y=y*2+yval;
        addedge(x^1,y);
        addedge(y^1,x);
    }
    //x=xval
    void add_con(int x,int xval){
        x=x*2+xval;
        addedge(x^1,x);
    }
    //
    void add_self(int x,int xval,int y,int yval){
        x=x*2+xval;
        y=y*2+yval;
        addedge(x,y);
    }
    int pre[maxn],lowlink[maxn],sccno[maxn],scc_cnt,dfs_clock;
    stack<int>stk;
    void dfs(int u)
    {
        pre[u]=lowlink[u]=++dfs_clock;
        stk.push(u);
        for (int i=head[u];i!=-1;i=edges[i].next){
            int v=edges[i].to;
            if (!pre[v]){
                dfs(v);
                lowlink[u]=min(lowlink[u],lowlink[v]);
            } else if (!sccno[v]){
                lowlink[u]=min(lowlink[u],pre[v]);
            }
        }
        if (lowlink[u]==pre[u]){
            scc_cnt++;
            int x;
            do{
                x=stk.top();
                stk.pop();
                sccno[x]=scc_cnt;
            }while (x!=u);
        }
    }
    void find_scc(int n)
    {
        dfs_clock=scc_cnt=0;
        clr(sccno,0);
        clr(pre,0);
        while (!stk.empty()) stk.pop();
        REP(i,n) if (!pre[i]) dfs(i);
    }
    bool solve(){
        find_scc(n);
        for (int i=0;i<n;i+=2){
            if (sccno[i]==sccno[i^1]) return false;
        }
        return true;
    }
}TwoSAT;

几何模板 点·线

不保证可靠 v0.1

int dcmp(double x){
    if (fabs(x)<EPS) return 0;
    return x>0?1:-1;
}
struct point{
    double x,y;
    point(){}
    point(double _x,double _y):x(_x),y(_y){}
    /**运算操作**/
    bool operator==(point a)const{
        return dcmp(a.x-x)==0&&dcmp(a.y-y)==0;
    }
    bool operator<(point a)const{
        return dcmp(x-a.x)==0?dcmp(y-a.y)<0:dcmp(x-a.x)<0;
    }
    friend point operator+(point a,point b){
        return point(a.x+b.x,a.y+b.y);
    }//向量+向量=向量
    friend point operator-(point a,point b){
        return point(a.x-b.x,a.y-b.y);
    }//点-点=向量
    friend point operator*(point a,double p){
        return point(a.x*p,a.y*p);
    }//向量*数=向量
    friend point operator/(point a,double p){
        return point(a.x/p,a.y/p);
    }//向量/数=向量
    /**基本信息计算**/
    double len(){
        return hypot(x,y);
    }
    double len2(){
        return x*x+y*y;
    }
    double distance(point p){
        return hypot(x-p.x,y-p.y);
    }
    /**向量变换**/
    point rotate(double rad){
        return point(x*cos(rad)-y*sin(rad),x*sin(rad)+y*cos(rad));
    }//绕起点逆时针旋转rad
    point rotate(point p,double angle)//绕点p逆时针旋转angle角度
    {
        point v=(*this)-p;
        double c=cos(angle),s=sin(angle);
        return point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
    }
    point rotleft(){
        return point(-y,x);
    }//逆时针转90度
    point rotright(){
        return point(y,-x);
    }//顺时针转90度
    point normal(){
        double L=len();
        return point(-y/L,x/L);
    }//单位法线即左转90度长度归一
    point trunc(double r){
        double l=len();
        if (!dcmp(l)) return *this;
        r/=l;
        return point(x*r,y*r);
    }//长度变为r
    /**读入与输出**/
    void input(){
        scanf("%lf%lf",&x,&y);
    }
    void output(){
        printf("%0.2f %0.2f\n",x,y);
    }
};
typedef point vect;
double dot(point a,point b){
    return a.x*b.x+a.y*b.y;
}
double cross(point a,point b){
    return a.x*b.y-a.y*b.x;
}
double area3p(point a,point b,point c){
    return cross(b-a,c-a)/2;
}//三角形abc的面积
double angle(vect a,vect b){
    return acos(dot(a,b)/a.len()/b.len());
}
point GetLineIntersection(point P,vect v,point Q,vect w){
    vect u=P-Q;
    double t=cross(w,u)/cross(v,w);
    return P+v*t;
}//直线交点
double ConvexPolygonArea(point *p,int n){
    double area=0;
    for (int i=1;i<n-1;i++) area+=cross(p[i]-p[0],p[i+1]-p[0]);
    return area/2;
}//多边形面积

struct line{
    point a,b;
    line(){}
    line(point _a,point _b){a=_a;b=_b;}
    line(point p,double angle){
        a=p;
        if (dcmp(angle-PI/2)==0) b=a+point(0,1);
        else b=a+point(1,tan(angle));
    }//倾斜角angle
    line (double _a,double _b,double _c){
        if (dcmp(_a)==0){
            a=point(0,-_c/_b);
            b=point(1,-_c/_b);
        }else if (dcmp(_b)==0){
            a=point(-_c/_a,0);
            b=point(-_c/_a,1);
        }else{
            a=point(0,-_c/_b);
            b=point(1,(-_c-_a)/_b);
        }
    }//ax+by+c=0
    void adjust(){
        if (b<a) swap(a,b);
    }//两点校准
    /**运算操作**/
    bool operator==(line v){
        return (a==v.a)&&(b==v.b);
    }
    /**基本信息计算**/
    double length(){
        return a.distance(b);
    }
    double angle(){
        double k=atan2(b.y-a.y,b.x-a.x);
        if (dcmp(k)<0) k+=PI;
        if (dcmp(k-PI)==0) k-=PI;
        return k;
    }
    /**线段相关**/
    int relation(point p){
        int c=dcmp(cross(p-a,b-a));
        if (c<0) return 1;//点在逆时针
        if (c>0) return 2;//点在顺时针
        return 3;//平行
    }
    bool pointonseg(point p){
        return dcmp(cross(p-a,b-a))==0&&dcmp(cross(p-a,p-b))<=0;
    }//点p在线段上?
    bool parallel(line v){
        return dcmp(cross(b-a,v.b-v.a))==0;
    }//与线段v平行?
    int segcrossseg(line v){
        int d1=dcmp(cross(b-a,v.a-a));
        int d2=dcmp(cross(b-a,v.b-a));
        int d3=dcmp(cross(v.b-v.a,a-v.a));
        int d4=dcmp(cross(v.b-v.a,b-v.a));
        if ((d1^d2)==-2&&(d3^d4)==-2)return 2;
        return ((d1==0&&dcmp(dot(v.a-a,v.a-b)<=0))||
                (d2==0&&dcmp(dot(v.b-a,v.b-b)<=0))||
                (d3==0&&dcmp(dot(a-v.a,a-v.b)<=0))||
                (d4==0&&dcmp(dot(b-v.a,b-v.b)<=0)));
    }//线段相交 0-不相交 1-非规范相交 2-规范相交
    /**直线相关**/
    int linecrosseg(line v){//直线v
        int d1=dcmp(cross(b-a,v.a-a));
        int d2=dcmp(cross(b-a,v.b-a));
        if ((d1^d2)==-2) return 2;
        return (d1==0||d2==0);
    }//0-平行 1-重合 2-相交
    int linecrossline(line v){
        if ((*this).parallel(v)) return v.relation(a)==3;
        return 2;
    }//0-平行 1-重合 2-相交
    point crosspoint(line v){
        double a1=cross(v.b-v.a,a-v.a);
        double a2=cross(v.b-v.a,b-v.a);
        return point((a.x*a2-b.x*a1)/(a2-a1),(a.y*a2-b.y*a1)/(a2-a1));
    }//交点
    double dispointtoline(point p){
        return fabs(cross(p-a,b-a))/length();
    }//点到线的距离
    double dispointtoseg(point p){
        if (dcmp(cross(p-b,a-b))<0||dcmp(cross(p-a,b-a))<0) return min(p.distance(a),p.distance(b));
        return dispointtoline(p);
    }
    /**输入输出**/
    void input(){
        a.input();
        b.input();
    }
    void output(){
        a.output();
        b.output();
    }
};


字典树Trie


const int CHARSET = 26;
const int MAX_N_NODES = int(3e5) + 10;
struct TrieNode
{
    TrieNode* next[CHARSET];
    int num;//记录是不是一个单词
    int value;//记录单词出现的次数
    TrieNode(){
       memset(next,0,sizeof(next));
       value=0;
       num=0;
    }
    void clear(){
       memset(next,0,sizeof(next));
       value=0;
       num=0;
    }
}*root;
TrieNode nodePool[MAX_N_NODES],*cur;
TrieNode* newNode(){
	TrieNode* t = cur++;
	t->clear();
	return t;
}
void trieInit() {
	cur=nodePool;
	root=newNode();
}
//插入:
void insert(char* s){
    TrieNode* p=root;
    int k=0;
    while(s[k]!='\0'){
        if(!p->next[s[k]-'a']) p->next[s[k]-'a']=newNode();
        p=p->next[s[k]-'a'];
        p->num++;
        k++;
    }
    p->value=1;
}
//查找
int find(char* s){
    TrieNode* p=root;
    int k=0;
    while(s[k]!='\0'&&p->next[s[k]-'a']){
        p=p->next[s[k]-'a'];
        k++;
    }
    if(s[k]=='\0') return p->num;
    return 0;
}
//DP查找
void dpfind(char* s,int pos){
    TrieNode* p=root;
    int k=0;
    while(s[k]!='\0'&&p->next[s[k]-'a']){
        p=p->next[s[k]-'a'];
        if (p->value==1){
            //do something like dp...
            //f[pos+k+1]=(f[pos+k+1]+f[pos])%MOD;
        }
        k++;
    }
}


扩展KMP


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MM=100005;
int next[MM],extand[MM];
char S[MM],T[MM];
void GetNext(const char *T){
     int len=strlen(T),a=0;
     next[0]=len;
     while(a<len-1 && T[a]==T[a+1]) a++;
     next[1]=a;
     a=1;
     for(int k=2;k<len;k++){
         int p=a+next[a]-1,L=next[k-a];
         if( (k-1)+L >= p){
             int j = (p-k+1)>0 ? (p-k+1) : 0;
             while(k+j<len && T[k+j]==T[j]) j++;
             next[k]=j;
             a=k;
         }
         else
             next[k]=L;
     }
}
void GetExtand(const char *S,const char *T){
     GetNext(T);
     int slen=strlen(S),tlen=strlen(T),a=0;
     int MinLen = slen < tlen ? slen : tlen;
     while(a<MinLen && S[a]==T[a]) a++;
     extand[0]=a;
     a=0;
     for(int k=1;k<slen;k++){
         int p=a+extand[a]-1, L=next[k-a];
         if( (k-1)+L >= p){
             int j= (p-k+1) > 0 ? (p-k+1) : 0;
             while(k+j<slen && j<tlen && S[k+j]==T[j]) j++;
             extand[k]=j;
             a=k;
         }
         else
             extand[k]=L;
     }
}
int main(){
    while(scanf("%s%s",S,T)==2){
         GetExtand(S,T);
         for(int i=0;i<strlen(T);i++)
             printf("%d ",next[i]);
         puts("");
         for(int i=0;i<strlen(S);i++)
             printf("%d ",extand[i]);
         puts("");
    }
    return 0;
}









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值