Pagini recente » Borderou de evaluare (job #2015328) | Cod sursa (job #768423) | Cod sursa (job #2643309) | Cod sursa (job #1416272) | Cod sursa (job #466850)
Cod sursa(job #466850)
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <set>
#include <algorithm>
using namespace std;
#define ll long long
#define N 100005
#define C 900010
#define K 2
#define fs first
#define sc second
#define mp make_pair
#define pii pair< int,int >
int n;
int a[N];
char c[C];
ll rez;
ll m[K]={1099957LL,1099823LL};
ll p[K]={29959LL,29837LL};
int h[K][2][N];
int pp[K][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("%lld\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[t][0][1]=a[1];
h[t][1][n-1]=a[n-1];
pp[t][0]=1;
pp[t][1]=p[t];
}
ll x;
for(int i=2; i<n; ++i)
{
for(int t=0; t<K; ++t)
{
x=((ll)h[t][0][i-1]*p[t]+(ll)a[i]);
if(x>=m[t])
x%=m[t];
h[t][0][i]=(int)x;
x=(ll)pp[t][i-1]*p[t];
if(x>=m[t])
x%=m[t];
pp[t][i]=(int)x;
}
}
for(int i=n-2; i>0; --i)
{
for(int t=0; t<K; ++t)
{
x=((ll)h[t][1][i+1]*p[t]+(ll)a[i]);
if(x>=m[t])
x%=m[t];
h[t][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[t][0][x-1]*(ll)pp[t][put];
if(aux1>=m[t])
aux1%=m[t];
aux1=(ll)h[t][0][i-1]-aux1;
if(aux1<0)
aux1+=m[t];
aux2=(ll)h[t][1][y+1]*(ll)pp[t][put];
if(aux2>=m[t])
aux2%=m[t];
aux2=(ll)h[t][1][i+1]-aux2;
if(aux2<0)
aux2+=m[t];
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("%lld\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;
}