9.13第一轮扫荡战果

1.处理内容

字符串部

manacher 1题

后缀数组 1题

后缀自动机 1题

最小表示法 1题

数学几何部

miller-rabin 1题

动态规划部

斜率优化 2题

2.字符串部

(1)双倍回文(SHOI2011)

暴力瞎搞搞

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
inline int read(){
	int i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<3)+(i<<1)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
#define stan 1111111
int len,n,r[stan],ans;
char s[stan],word[stan];
void manachar(){
	int rb=0,ctr=0,length=0;
	for(int i=1;ii) length=min(r[2*ctr-i],rb-i);
		else length=1;
		while(s[i+length]==s[i-length]) ++length;
		r[i]=length;
		if(length+i>rb){
			ctr=i;
			rb=length+i;
		}
	}
}
signed main(){
	len=read();
	scanf("%s",word);
	n=2*len+3;
	for(int i=0;i>1);
		if(!(j&1)) ++j;
		for(;ji){
				ans=max(ans,(i-j)*2);
				break;
			}
	}
	write(ans);
	return 0;
}
(2)字符加密(JSOI2007)

裸题不解释

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
inline int read(){
	int i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<3)+(i<<1)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
#define stan 222222
int len,sa[stan],tmp[stan],rk[stan],k;
char word[stan];
inline bool cmp(int i,int j){
	if(rk[i]!=rk[j]) return  rk[i]
(3)substrings(SPOJ8222)

懒癌发作http://hzwer.com/4420.html

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
inline int read(){
	int i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<3)+(i<<1)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
#define stan 555555
int r[stan],t[stan],num[stan],f[stan],len;
char s[stan];
struct sam{
	int last,cnt;
	int a[1000005][26],fa[1000005],step[1000005],val[1000005],sum[1000005];
	int v[500005],q[1000005];
	sam(){
		last=++cnt;
	}
	void extend(int c){
		int p=last,np=last=++cnt;
		step[np]=step[p]+1;
		while(!a[p][c]&&p) a[p][c]=np,p=fa[p];
		if(!p) fa[np]=1;
		else{
			int q=a[p][c];
			if(step[p]+1==step[q]) fa[np]=q;
			else{
				int nq=++cnt;
				step[nq]=step[p]+1;
				memcpy(a[nq],a[q],sizeof(a[q]));
				fa[nq]=fa[q];
				fa[np]=fa[q]=nq;
				while(a[p][c]==q) a[p][c]=nq,p=fa[p];
			}
		} 
	}
}sam;
signed main(){
	scanf("%s",s+1);
	len=strlen(s+1);
	for(int i=1;i<=len;++i)
		sam.extend(s[i]-'a');
	for(int i=1,p=1;i<=len;++i){
		p=sam.a[p][s[i]-'a'];
		++r[p];
	}
	for(int i=1;i<=sam.cnt;++i)
		++num[sam.step[i]];
	for(int i=1;i<=len;++i)
		num[i]+=num[i-1];
	for(int i=1;i<=sam.cnt;++i)
		t[num[sam.step[i]]--]=i;
	for(int i=sam.cnt;i;--i)
		r[sam.fa[t[i]]]+=r[t[i]];
	for(int i=1;i<=sam.cnt;++i)
		f[sam.step[i]]=max(f[sam.step[i]],r[i]);
	for(int i=len;i;--i) 
		f[i]=max(f[i],f[i+1]);
	for(int i=1;i<=len;++i){
		write(f[i]);puts(" ");
	}
	return 0;
}
(4)工艺

投诉b站

9028ms>10000ms>10772ms

当然你写最小表示法飞过

可惜这个算法虽然简洁而美,但是实际上可以被后缀数组或后缀自动机替代了

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
inline int read(){
	int i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<3)+(i<<1)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
#define stan 666666
int num[stan],n;
int getmin(int *s){
    int i=0,j=1,k=0,tag;
    while(i0) i+=k+1; 
            else j+=k+1;
            if (i==j) j++;
            k=0;
        }
    }
    return i
3.数学几何部

(1)Miller-Rabin

还是甩链接http://blog.csdn.net/thy_asdf/article/details/51347390

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define int long long
using namespace std;
inline int read(){
	int i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<3)+(i<<1)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
int maxn,T,x;
int ksc(int a,int b,int p){
    int tmp=(a*b-(int)((long double)a/p*b+1e-8)*p);
    return tmp<0?tmp+p:tmp;
}
int ksm(int a,int b,int c){
	int ret=1;
	while(b){
		if(b&1) ret=ksc(ret,a,c);
		b>>=1;
		a=ksc(a,a,c);
	}
	return ret;
}
int gcd(int x,int y){
	if(y) return gcd(y,x%y);
	return x;
}
bool check(int a,int n,int r,int s){
	int y=ksm(a,r,n),tmp=y;
	for(int i=1;i<=s;++i){
		y=ksc(y,y,n);
		if(y==1&&tmp!=1&&tmp!=n-1) return true;
		tmp=y;
	}
	return (y==1)?false:true;
}
bool mr(int n){
	if(n<=1||n%2==0&&n!=2) return false;
	if(n==2) return true;
	int r=n-1,s=0;
	while(r%2==0){
		r>>=1;
		++s;
	}
	for(int i=0;i<10;++i)
		if(check(rand()%(n-1)+1,n,r,s)) return false;
	return true;
}
int rho(int n,int c){
	int k=2,x=rand()%n,y=x,p=1;
	for(int i=1;p==1;++i){
		x=(ksc(x,x,n)+c)%n;
		p=abs(x-y);
		p=gcd(n,p);
		if(i==k) y=x,k+=k;
	} 
	return p;
}
void solve(int n){
	if(n==1) return ;
	if(mr(n)){
		maxn=max(maxn,n);
		return ;
	}
	int tmp=n;
	while(tmp==n)
		tmp=rho(n,rand()%(n-1)+1);
	solve(tmp);
	solve(n/tmp);
	return ;
}
signed main(){
	T=read();
	while(T--){
		x=read();maxn=0;
		solve(x);
		if(maxn==x) puts("Prime");
		else{
			write(maxn);
			putchar('\n');
		}
	}
	return 0;
}
4.动态规划部

(1)小P的牧场

仓库建设的双倍经验http://www.lydsy.com/JudgeOnline/problem.php?id=3437

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define int long long
using namespace std;
inline int read(){
	int i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<3)+(i<<1)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
#define stan 1111111
int n,a[stan],b[stan],sum[stan],pre[stan],f[stan],l,r,que[stan];
double slope(int k,int j){
	return double(f[k]-f[j]+pre[k]-pre[j])/double(sum[k]-sum[j]);
}
signed main(){
	n=read();
	for(int i=1;i<=n;++i)
		a[i]=read();
	for(int i=1;i<=n;++i){
		b[i]=read();
		sum[i]=sum[i-1]+b[i];
		pre[i]=pre[i-1]+b[i]*i;
	}
	for(int i=1;i<=n;++i){
		while(lslope(que[r],i)) --r;
		que[++r]=i;
	}
	write(f[n]);
	return 0;
}
(2)防御准备

其实一样水http://www.lydsy.com/JudgeOnline/problem.php?id=3156

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define int long long
using namespace std;
inline int read(){
	int i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<3)+(i<<1)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
#define stan 111111
int f[stan],a[stan],n,l,r,que[stan];
double slope(int k,int j){
	return double(2*(f[k]-f[j])+k*k+k-j*j-j)/double(2*k-2*j);
}
signed main(){
	n=read();
	for(int i=1;i<=n;++i)
		a[i]=read();
	for(int i=1;i<=n;++i){
		while(lslope(que[r],i)) --r;
		que[++r]=i;
	}
	write(f[n]);
	return 0;
}
唔,莫名忧伤








你可能感兴趣的:(OI,字符串算法纲,动态规划纲)