KMP:
【NOI2014】 动物园
# include <cstring>
# include <cstdio>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int maxl = 1000010;
char s[maxl];
int pre[maxl],dep[maxl];
void getFail(){
int l = strlen(s);
int j=0; dep[1]=1;
for (int i=1;i<l;++i){
while (j&&s[j]!=s[i]) j=pre[j];
if (s[j]==s[i]) ++j;
pre[i+1]=j;
dep[i+1]=dep[j]+1;
}
}
void getAns(){
ll ans=1;
int l = strlen(s);
int j=0;
for (int i=1;i<l;++i){
while (j&&s[j]!=s[i]) j=pre[j];
if (s[j]==s[i]) ++j;
while (j>(i+1)/2 && j) j=pre[j];
ans=(ans*(dep[j]+1))%mod;
}
printf("%lld\n",ans);
}
int main(){
int T; scanf("%d",&T);
while (T--){
scanf("%s",s);
getFail();
getAns();
}
return 0;
}
线段树:(采用神奇实现方法)
【Luogu#3372】区间加/区间和
# include <cstdio>
using namespace std;
typedef long long ll;
const int maxn = 100010;
int n,m;
int ra[maxn];
namespace Seg{
ll sum[maxn<<2];
int tag[maxn<<2],siz[maxn<<2];
void pup(int x){ sum[x]=sum[x<<1]+sum[x<<1|1]; }
void ptg(int x,int tg){ tag[x]+=tg; sum[x]+=siz[x]*tg; }
void pdw(int x){ if (tag[x]) ptg(x<<1,tag[x]),ptg(x<<1|1,tag[x]),tag[x]=0; }
void init(int x,int l,int r)
{
sum[x]=tag[x]=0; siz[x]=r-l+1;
if (l==r){ sum[x]=ra[l]; return; }
int m = (l+r)>>1;
init(x<<1,l,m); init(x<<1|1,m+1,r);
pup(x);
}
int opty,opl,opr,opg;
ll opans;
void step(int x,int l,int r)
{
if (opl <= l && r <= opr)
{
if (opty == 1) ptg(x,opg);
if (opty == 2) opans += sum[x];
return;
}
int m = (l+r)>>1; pdw(x);
if (opl<=m) step(x<<1,l,m);
if (opr>m) step(x<<1|1,m+1,r);
if (opty == 1) pup(x);
}
}
void work(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;++i) scanf("%d",ra+i);
Seg::init(1,1,n);
for (int i=1;i<=m;++i)
{
scanf("%d%d%d",&Seg::opty,&Seg::opl,&Seg::opr);
if(Seg::opty==1) scanf("%lld",&Seg::opg);
Seg::opans=0; Seg::step(1,1,n);
if(Seg::opty==2) printf("%lld\n",Seg::opans);
}
}
int main(){
work();
return 0;
}