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;
}
唔,莫名忧伤