sone2(未完成)

先留个半完成代码

边看论文边看题解写的...难受..

#include<cstdio>
#include<cstring>
namespace utils{
	inline int max(int a,int b){ return a>b?a:b; }
	inline int min(int a,int b){ return a<b?a:b; }
	inline void tensen(int&a,int b){ if(a>b)a=b; }
	inline void relax(int&a,int b){ if(a<b)a=b; }
	///Trivial helping functions
	inline int l2f(int n){
		float a(n);
		return (((*(int*)&a)>>23)+1)&31;//float provides 23-bit accuracy, enough for RQM-use
	}
	inline void swap(int&a,int&b){ a^=(b^=(a^=b)); }
}using namespace utils;
namespace qio{ //Code Tricks: quick I/O (collapsed) namespace used.
	#define maxio 5000010
	char buf[maxio],*cur,*ecr;
	char obuf[maxio],*ocr;
	inline void readin(){ ecr=(cur=buf)+fread(buf,1,maxio,stdin); ocr=obuf; }
	inline int nxtint(){
		while(*cur<'0' || *cur>'9')++cur;
		int x=*(cur++)-'0'; while(*cur<='9'&&*cur>='0') x=x*10+*(cur++)-'0';
		return x;
	}
	inline void print(int n){
		if(n>=10) print(n/10),*(ocr++)=n%10+'0'; else *(ocr++)=n+'0';
	}
	inline void flush(){ fwrite(obuf,1,ocr-obuf,stdout); ocr=obuf; }
	#define putc(x) (*(ocr++)=x)
	#define getc(x) (x=*(cur++))
	#define scanner qio
}using namespace qio;
#define Rx nxtint()
struct rmq_st{ //A trivial Objective-Range Minimun Query Solver involves a Sparse Table
	#define maxn 100010
	#define lmaxn 18
	int sttbl[lmaxn][maxn];
	inline void init(int n,int*v){
		int*p=sttbl[0],*q;
		for(int i=0;i<n;++i) p[i]=v[i];
		for(int i=1,h=1,j=2;j<n;++i,h<<=1,j<<=1){
			q=sttbl[i-1];
			p=sttbl[i];
			for(int k=0,_=n-j;k<=_;++k){
				p[k]=min(q[k],q[k+h]);
			}
		}
	}
	inline int operator()(int l,int r){
		int p=l-r+1,t=l2f(p);
		return min(sttbl[t][l],sttbl[t][r-(1<<t)+1]);
	}
	#undef maxn
	#undef lmaxn
};
typedef struct Suffix_Array{
	#define maxn 100010
	int v[maxn*3],qa[maxn*3],qb[maxn*3],sav[maxn*3],sa[maxn*3];
	inline bool cmp1(int*v,int a,int b){
		return v[a]==v[b] && v[a+1]==v[b+1] && v[a+2]==v[b+2];
	}
	inline bool cmp21(int*v,int a,int b){
		return v[a]<v[b] || (v[a]==v[b] && sav[a+1]<sav[b+1]);
	}
	inline bool cmp2(int d,int*v,int a,int b){
		if(d==1){
			return cmp21(v,a,b);
		}else{
			return v[a]<v[b] || (v[a]==v[b] && cmp21(v,a+1,b+1));
		}
	}
	inline void radixsort(int*v,int*q,int*sa,int n,int m){
		static int c[maxn];
		for(int i=0;i<m;++i)c[i]=0;
		for(int i=0;i<n;++i)++c[v[q[i]]];
		for(int i=1;i<m;++i)c[i]+=c[i-1];
		for(int i=n-1;~i;--i)sa[--c[v[q[i]]]]=q[i];
	}
	#define f(x) (qx=(x)/3,qxa=qx*3,(x)-qxa==1?qx:qx+na)
	#define rf(x) ((x)<na?3*(x)+1:3*((x)-na)+2)
	inline void dc3(int*v,int*sa,int n,int m){
		int i,j,k,*nv=v+n+3,*nsa=sa+n+3,na=(n+2)/3,nbc=0,lab;
		int qx,qxa;
		v[n]=v[n+1]=v[n+2]=0;
		for(int i=0;i<n;++i)if(i%3)qa[nbc++]=i;
		if(n%3==1) qa[nbc++]=n;
		radixsort(v+2,qa,qb,nbc,m);
		radixsort(v+1,qb,qa,nbc,m);
		radixsort(v  ,qa,qb,nbc,m);
		for(i=lab=0;i<nbc;++lab,i=j+1){
			for(j=i;j<nbc-1 && cmp1(v,qb[j],qb[j+1]);++j);
			for(k=i;k<=j;++k) nv[f(qb[k])]=lab;
		}
		if(lab<nbc) dc3(nv,nsa,nbc,lab); else for(int i=0;i<nbc;++i) nsa[nv[i]]=i;
		for(i=j=0;i<nbc;++i) if(nsa[i]<na) qb[j++]=3*nsa[i];
		radixsort(v,qb,qa,na,m);
		for(int i=0;i<nbc;++i) sav[qb[i]=rf(nsa[i])]=i;
		for(i=lab=0,j=(n%3==1);i<na && j<nbc;){
			sa[lab++]=cmp2(qb[j]%3,v,qa[i],qb[j])?qa[i++]:qb[j++];
		}
		while(i<na) sa[lab++]=qa[i++];
		while(j<nbc) sa[lab++]=qb[j++];
	}
	int rnk[maxn],height[maxn],n;
	inline void initHeight(int len){
		for(int i=0;i<len;++i) rnk[sa[i]]=i;
		for(int i=0;i<len;++i){
			if(rnk[i]){
				int j=0; if(i) j=max(0,height[rnk[i-1]]-1);
				while(i+j<len && sa[rnk[i]-1]+j<len && v[i+j]==v[sa[rnk[i]-1]+j])++j;
				height[rnk[i]]=j;
			}
		}
	}
	///the above is trivial DC3 implementation
	inline void init(char*s,int ln){
		n=ln;
		for(int i=0;i<n;++i) v[i]=s[i];
		dc3(v,sa,n,256); initHeight(n);
	}
	inline void init(){//read from stdin
		n=Rx;int ma=0;
		for(int i=0;i<n;++i) tensen(ma,v[i]=Rx);
		dc3(v,sa,n,ma+5); initHeight(n);
	}
	///the above is trivial initial functions for Objective-SuffixArray implementation.
	#undef  maxn
} SAX;
#define Pair(v,t,x,y) struct v{\
	t x,y;\
	inline v(){}\
	inline v(t x,t y):x(x),y(y){}\
}
Pair(ssp,int,l,r);	// struct to store substring position
Pair(ans,int,x,y);	// struct to store answer for function F
Pair(sap,int,l,r);	// struct to store position in array SA
typedef ans spr;
inline ans operator+(const ans&a,const ans& b){
	ans p(a.x,a.y);
	if(b.x>a.x)p=b;
	else if(a.x==b.x) p.y+=b.y;
	return p;
}
struct SRMQ{
	//RMQ with size
	//which would be solved with doubling-based method
	#define maxn 100010
	#define lmaxn 18
	spr sttbl[lmaxn][maxn];
	inline void init(int n,int*v){
		spr*p=sttbl[0],*q;
		for(int i=0;i<n;++i) p[i]=ans(v[i],1);
		for(int i=1,h=1,j=2;j<n;++i,h<<=1,j<<=1){
			q=sttbl[i-1];
			p=sttbl[i];
			for(int k=0,_=n-j;k<=_;++k){
				p[k]=q[k]+q[k+h];
			}
		}
	}
	inline spr operator()(int l,int r){
		if(l>r)return spr(0,0);
		int k=l;
		spr answer(0,0);
		for(int i=18;~i;--i){
			int B=k+(1<<i);
			if(B-1<=r){
				answer=answer+sttbl[i][k];
				k=B;
			}
		}
		return answer;
	}
	#undef maxn
	#undef lmaxn
};
struct tsolver{//tsolver helps to solve Operations 3 and 4
	SAX str;
	rmq_st stbl;
	SRMQ stbl2;
	#define maxn 100010
	#define _sa str.sa
	#define _rk str.rnk
	#define _ht str.height
	#define _sz str.n
	
	#define ssp_invalid(sspx) (sspx.l<0 || sspx.l>=_sz || sspx.r<0 || sspx.r>=_sz)
	#define ssp_reduced_invalid(sspx) (sspx.l<0 || sspx.r<0)
	#define ssp_lengthd(sspx) (sspx.r-sspx.l+1)
	////LCP
	inline int LCP(int x,int y){ // should input a sap
		if(x==y) return _sz-_sa[x];
		if(x<y)x^=(y^=(x^=y));
		if(x>=_sz) return 0;
		if(y>=_sz) return 0;
		return stbl(x+1,y);
	}
	//initialization!
	inline void init(){
		static int vr[maxn];
		str.init();
		stbl.init(_sz,_ht);
		for(int i=0;i<_sz;++i) vr[i]=LCP(_rk[1],_rk[i]);
		stbl2.init(_sz,vr);
	}
	////query left bound
	inline int find_l(int a,int len){
		int k=a;
		for(int i=18;i>=0;++i){
			int A=k-(1<<i);
			if(A>=0 && LCP(A,a)>=len) k=A;
		}
		return k;
	}
	////query right bound. Similar.
	inline int find_r(int a,int len){
		int k=a;
		for(int i=18;i>=0;++i){
			int A=k+(1<<i);
			if(A<_sz && LCP(a,A)>=len) k=A;
		}
		return k;
	}
	////combine the two
	inline sap find_str_bounds(ssp x){
		int len=x.r-x.l+1;
		return sap(find_l(_rk[x.l],len),find_r(_rk[x.l],len));
	}
	////cmp two strings pos@($a&$b) wiz len $len
	inline int compare_string(int a,int b,int len){
		if(a==b)return 0;
		int A=LCP(_rk[a],_rk[b]);
		if(A>=len) return 0;//equal
		if(_rk[a]<_rk[b]) return -1;
		if(_rk[a]>_rk[b]) return  1;
	}
	inline int FindConcat(ssp a,ssp b){
		if(ssp_reduced_invalid(a)||ssp_reduced_invalid(b))return -1;	//range checking should always come first
		sap Dx=find_str_bounds(a);	//find occurences of substring a
		int i,k=Dx.l,La=ssp_lengthd(a),Lb=ssp_lengthd(b);	
		if(compare_string(_sa[Dx.l]+La,b.l,Lb)>0) return 0;	//simple boundary test
		if(compare_string(_sa[Dx.r]+La,b.l,Lb)<0) return 0;	
			//find answer by doubling
		for(int i=18;~i;--i){
			int B=k+(1<<i);
			if(B<=Dx.r && compare_string(_sa[B]+La,b.l,Lb)<0) k=B;
		}
		if(compare_string(_sa[k]+La,b.l,Lb)<0)++k;	//last modifies
		int lcx=LCP(_rk[_sa[k]+La],_rk[b.l]);	//check fitness
		if(lcx>=Lb) return _sa[k];	//if fit
		return -1;	//or if not
	}
	////things below are for border tree
	#undef _sa
	#undef _rk
	#undef _ht
	#undef _sz
	#undef maxn
};
struct bt_edge{
	int t;
	bt_edge*n;
};
struct bt_node{
	int x,y,z,DF;
	int fa,sh,ma;
	bt_edge*h,*b;
};
struct border_tree{
	#define maxn 100010
	int p[maxn],f[maxn],n;
	bt_node tr[maxn],*tre;
	bt_edge eds[maxn*2],*ek;
	inline void addedge(int f,int t){
		*ek=(bt_edge){t,tre[f].h};
		tre[f].h=ek++;
	}
	inline void addBedge(int f,int t){
		*ek=(bt_edge){t,tre[f].b};
		tre[f].b=ek++;
	}
	inline void KMP_fail(int*px,int len){
		ek=eds; tre=tr+1;//add tolerance for node#-1
		n=len;
		for(int i=0;i<n;++i) p[i]=px[i];
		f[0]=-1;
		for(int i=1,j=-1;i<n;++i){
			for(;(~j) && p[j+1]!=p[i];j=f[j]);
			if(p[j+1]==p[i])++j;
			f[i]=j;
		}
		for(int i=0;i<n;++i) addedge(f[i],i);///making a KMP automaton
	}
	#define ue bt_edge
	#define un bt_node
	inline void dfs1(int u){
		un*p=tre+u;
		for(ue*i=tre[u].h;i;i=i->n){
			int A=i->t;
			un*kn=tre+A;
			kn->DF=u;
			if(u&&u*2>=A){
				//A is a cycling border
				kn->y=A-u;
				kn->x=u%kn->y;
				if(p->x==kn->x && p->y==kn->y) kn->z=p->z+1; else kn->z=2;
			}else{
				kn->x=u;
				kn->y=A-u;
				kn->z=1;
			}
			dfs1(A);
		}
	}
	inline void dfs2(int u){
		un*p=tre+u;
		for(ue*i=tre[u].h;i;i=i->n){
			un*kn=tre+i->t;
			if(kn->z==2 && p->z==1){
				p->x=kn->x;
				p->y=kn->y;
			}
			dfs2(i->t);
		}
	}
	inline void dfs3(int u){
		un*p=tre+u;
		for(ue*i=tre[u].h;i;i=i->n){
			un*kn=tre+i->t;
			if(p->z && kn->z==p->z+1) kn->fa=p->fa;
			else{
				addBedge(p->fa,i->t);
				kn->fa=i->t;
				kn->sh=p->fa;
			}
			dfs3(i->t);
		}
		relax(tre[p->fa].ma,p->z);
	}
	inline void init(int*px,int len){
		KMP_fail(px,len);
		dfs1(-1);
		dfs2(-1);
		dfs3(-1);
	}
	
};
int main(){ readin();
	return 0;
}


其实半完成都算不上...

似乎差不多半完成了.

现在好想吐槽sone爷的代码...完全没有语义!完全没有注释!

posted @ 2016-01-06 22:47  zball  阅读(441)  评论(0编辑  收藏  举报