NGUNSTTD-PO
Name: NeverGiveUpNeverSurrenderTerribleTerribleDamage-PowerOverwhelming
Usage: Put it before main functionTags: 头文件 循环 常用语句
/** 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
//图论模板
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;
}