Pagini recente » Cod sursa (job #180826) | Cod sursa (job #1623153) | Cod sursa (job #2729948) | Cod sursa (job #1482297) | Cod sursa (job #466853)
Cod sursa(job #466853)
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <set>
#include <algorithm>
using namespace std;
#define ll int
#define N 100005
#define C 900010
#define fs first
#define sc second
#define mp make_pair
#define K 1
#define pii pair< int,int >
int n;
int a[N];
char c[C];
ll rez;
//ll m=1099957LL;
ll m=29959;
ll p=173;
int h[2][N];
int pp[N];
set< pii > se;
inline void citire()
{
scanf("%d\n",&n);
fgets(c,C,stdin);
int x=0;
int j=0;
bool neg=false;
for(int i=1; i<=n; ++i)
{
if(c[j]=='-')
{
++j;
neg=true;
}
else
neg=false;
x=0;
for(; c[j]>='0' && c[j]<='9'; ++j)
x=x*10+(c[j]-'0');
if(neg)
a[i]=-x;
else
a[i]=x;
++j;
}
}
inline void rezolva1()
{
if(n==1)
{
printf("0\n");
return;
}
int x,y;
int cat;
bool ok;
int lun;
for(int i=1; i<n; ++i)
{
x=i;
y=i+1;
cat=a[x]+a[y];
--x;
++y;
++rez;
ok=true;
lun=1;
for(; ok && x>0 && y<=n; --x,++y)
{
if(a[x]+a[y]==cat)
{
++rez;
++lun;
}
else
ok=false;
}
//printf("%d ",lun);
}
//printf("\n");
printf("%d\n",rez);
}
inline void precalc()
{
for(int i=1; i<n; ++i)
a[i]-=a[i+1];
int nr=0;
set< pii >::iterator it;
for(int i=1; i<n; ++i)
{
it=se.lower_bound(mp(a[i],0));
if(it==se.end() || (it->fs)!=a[i])
{
++nr;
se.insert(mp(a[i],nr));
a[i]=nr;
continue;
}
a[i]=(it->sc);
}
//for(int t=0; t<K; ++t)
//{
h[0][1]=a[1];
h[1][n-1]=a[n-1];
pp[0]=1;
pp[1]=p;
//}
ll x;
for(int i=2; i<n; ++i)
{
//for(int t=0; t<K; ++t)
//{
x=((ll)h[0][i-1]*p+(ll)a[i]);
if(x>=m)
x%=m;
h[0][i]=(int)x;
x=(ll)pp[i-1]*p;
if(x>=m)
x%=m;
pp[i]=(int)x;
//}
}
for(int i=n-2; i>0; --i)
{
//for(int t=0; t<K; ++t)
//{
x=((ll)h[1][i+1]*p+(ll)a[i]);
if(x>=m)
x%=m;
h[1][i]=(int)x;
//}
}
}
inline bool eok(int i,int x,int y)
{
int put=i-x;
ll aux1,aux2;
//for(int t=0; t<K; ++t)
//{
aux1=(ll)h[0][x-1]*(ll)pp[put];
if(aux1>=m)
aux1%=m;
aux1=(ll)h[0][i-1]-aux1;
if(aux1<0)
aux1+=m;
aux2=(ll)h[1][y+1]*(ll)pp[put];
if(aux2>=m)
aux2%=m;
aux2=(ll)h[1][i+1]-aux2;
if(aux2<0)
aux2+=m;
if(aux1!=aux2)
return false;
//}
return true;
}
inline int minim(int x,int y)
{
return ( (x<y) ? (x) : (y) );
}
inline void caut(int i)
{
++rez;
if(a[i-1]!=a[i+1])
{
//printf("1 ");
return;
}
int lim=minim(i-1,n-i-1);
int p=1,u=lim;
int m;
while(p+1<u)
{
m=(p+u)>>1;
if(eok(i,i-m,i+m))
p=m;
else
u=m-1;
}
if(p+1<=lim)
{
if(eok(i,i-p-1,i+p+1))
{
++p;
if(p+1<=lim)
{
if(eok(i,i-p-1,i+p+1))
++p;
}
}
}
//printf("%d ",p+1);
rez+=(ll)p;
}
inline void rezolva2()
{
precalc();
++rez;
++rez;
//printf("1 ");
for(int i=2; i+1<n; ++i)
caut(i);
//printf("1\n");
printf("%d\n",rez);
}
int main()
{
freopen("numarare.in","r",stdin);
freopen("numarare.out","w",stdout);
citire();
if(n==1)
{
printf("0\n");
return 0;
}
if(n==2)
{
printf("1\n");
return 0;
}
//if(n<3010)
// rezolva1();
//else
rezolva2();
return 0;
}