最小表示法(poj1509)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
const int maxn=1e5+7;
int T,n;
char s[maxn];
char cc;ll ff;
template<typename T>void read(T& aa) {
aa=0;ff=1; cc=getchar();
while(cc!=‘-‘&&(cc<‘0‘||cc>‘9‘)) cc=getchar();
if(cc==‘-‘) ff=-1,cc=getchar();
while(cc>=‘0‘&&cc<=‘9‘) aa=aa*10+cc-‘0‘,cc=getchar();
aa*=ff;
}
int solve() {
int i=0,j=1,k=0,t;
while(i<n&&j<n&&k<n) {
t=s[(i+k)%n]-s[(j+k)%n];
if(t==0) k++;
else {
if(t>0) i+=k+1;
else j+=k+1;
if(i==j) j++;
k=0;
}
}
return min(i,j);
}
int main() {
read(T);
while(T--) {
scanf("%s",s);
n=strlen(s);
printf("%d\n",solve()+1);
}
return 0;
}
sg函数(hdu1848)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
const int maxn=1000+7;
int n[3],f[maxn],sg[maxn],ans;
char cc;ll ff;
template<typename T>void read(T& aa) {
aa=0;ff=1; cc=getchar();
while(cc!=‘-‘&&(cc<‘0‘||cc>‘9‘)) cc=getchar();
if(cc==‘-‘) ff=-1,cc=getchar();
while(cc>=‘0‘&&cc<=‘9‘) aa=aa*10+cc-‘0‘,cc=getchar();
aa*=ff;
}
bool vis[maxn];
int get_sg(int x) {
memset(vis,0,sizeof(vis));
for(int i=1;f[i]<=x;++i) vis[sg[x-f[i]]]=1;
for(int i=0;;++i) if(!vis[i]) return i;
}
int main() {
f[0]=f[1]=1;
for(int i=2;i<=1000;++i) {
f[i]=f[i-1]+f[i-2];
if(f[i]>1000) break;
}
memset(sg,-1,sizeof(sg));sg[0]=0;
for(int i=1;i<=1000;++i) sg[i]=get_sg(i);
read(n[0]); read(n[1]); read(n[2]);
while(n[0]||n[1]||n[2]) {
ans=sg[n[0]]^sg[n[1]]^sg[n[2]];
if(ans) printf("Fibo\n");
else printf("Nacci\n");
read(n[0]); read(n[1]); read(n[2]);
}
return 0;
}
树hash(bzoj4337)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
const int maxn=50+7;
const ll base=1031,bs=1234,bse=5107043,mod=1000000007;
int n,m,fa[maxn],ans;
char cc;ll ff;
template<typename T>void read(T& aa) {
aa=0;ff=1; cc=getchar();
while(cc!=‘-‘&&(cc<‘0‘||cc>‘9‘)) cc=getchar();
if(cc==‘-‘) ff=-1,cc=getchar();
while(cc>=‘0‘&&cc<=‘9‘) aa=aa*10+cc-‘0‘,cc=getchar();
aa*=ff;
}
int fir[maxn],nxt[2*maxn],to[2*maxn],e=0;
void add(int x,int y) {
to[++e]=y; nxt[e]=fir[x]; fir[x]=e;
to[++e]=x; nxt[e]=fir[y]; fir[y]=e;
}
ll hsh[maxn],now[maxn],zz[maxn],t,fz[maxn],tt;
bool vis[maxn];
void get_hash(int pos) {
vis[pos]=1;
for(int y=fir[pos];y;y=nxt[y])
if(!vis[to[y]]) get_hash(to[y]);
t=0;
for(int y=fir[pos];y;y=nxt[y])
if(!vis[to[y]]) zz[++t]=now[to[y]];
vis[pos]=0;
if(!t) {
now[pos]=bs;
return;
}
sort(zz+1,zz+t+1);
for(int i=1;i<=t;++i) {
now[pos]^=zz[i];
now[pos]=now[pos]*base%mod;
}
}
int main() {
read(m);
for(int i=1;i<=m;++i) {
read(n);
memset(fir,0,sizeof(fir)); e=0; tt=0;
for(int j=1;j<=n;++j) {
read(fa[j]);
if(fa[j]) add(fa[j],j);
}
for(int j=1;j<=n;++j) {
memset(now,0,sizeof(now));
memset(vis,0,sizeof(vis));
get_hash(j); fz[j]=now[j];
}
sort(fz+1,fz+n+1);
for(int j=1;j<=n;++j) hsh[i]=(hsh[i]^fz[j])*bse%mod;
for(int j=i;j;--j) if(hsh[j]==hsh[i]) ans=j;
printf("%d\n",ans);
}
return 0;
}
/*
4
4 0 1 1 2
4 2 0 2 3
4 0 1 1 1
4 0 1 2 3
*/
笛卡尔树(poj1785)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
const int maxn=50000+7;
int n,p[maxn],pr[maxn];
char c,s[maxn][117];
char cc;ll ff;
template<typename T>void read(T& aa) {
aa=0;ff=1; cc=getchar();
while(cc!=‘-‘&&(cc<‘0‘||cc>‘9‘)) cc=getchar();
if(cc==‘-‘) ff=-1,cc=getchar();
while(cc>=‘0‘&&cc<=‘9‘) aa=aa*10+cc-‘0‘,cc=getchar();
aa*=ff;
}
int ui;
bool cmp(int x,int y) {
return strcmp(s[x],s[y])<=0;
}
int son[maxn][2],root;
int zz[maxn],t,last;
void print_ans(int pos) {
printf("(");
if(son[pos][0]) print_ans(son[pos][0]);
printf("%s/%d",s[pos],pr[pos]);
if(son[pos][1]) print_ans(son[pos][1]);
printf(")");
}
void solve() {
t=0;
memset(son,0,sizeof(son)); root=0;
for(int i=1;i<=n;++i) {
last=0;
while(t&&pr[zz[t]]<pr[p[i]]) {
last=zz[t];
t--;
}
son[p[i]][0]=last;
if(!t) root=p[i];
else son[zz[t]][1]=p[i];
zz[++t]=p[i];
}
print_ans(root);
}
int main() {
scanf("%d",&n);
while(n) {
for(int i=1;i<=n;++i) {
p[i]=i;
scanf("%*[ ]%[^/]/%d",s[i],&pr[i]);
}
sort(p+1,p+n+1,cmp);
solve();printf("\n");
scanf("%d",&n);
}
return 0;
}
/*
7 a/7 b/6 c/5 d/4 e/3 f/2 g/1
7 a/1 b/2 c/3 d/4 e/5 f/6 g/7
7 a/3 b/6 c/4 d/7 e/2 f/5 g/1
0
*/
生成函数留坑