fork(1) download
  1. // O(n) megoldás
  2. // Legyen F(m)=|{i | a[i]>=c és i<=m}|, azaz c-nél nem kisebb tagok száma az első m tag között
  3. // Belátható, hogy (a[k],..,a[m]) pontosan akkor értékes, ha F(m)-F(k-1)>=(m-k+1)/2 ( és k<=m )
  4. // Legyen G(m)=2*F(m)-m
  5. // Kell: G(m)-G(k-1)>=0, azaz G(k-1)<=G(m) ( és persze k<=m )
  6. // Legyen H(m)=G(m)+n, ekkor 0<=H(m)<=2*n
  7.  
  8. // Legyen (adott m-re): T[p]=|{i | i<m és H(i)<=p}|
  9. // Ki fogjuk használni, hogy abs(H(m)-H(m+1))<=1
  10. // ezzel tree-k helyett tároljuk, hogy mennyivel kell majd növelni a T[] tömb elemeit
  11. // módosításokat az inc[] tömbben tároljuk: T[p]+sum(inc[x]:x<=p) a pontos érték
  12. // adott v=H(m) esetén inc[p]=0 lesz, ha p<=v+1, így
  13. // a következő pozicíóban is a T[] tömb eleme pontos lesz ( hiszen H(m+1)<=v+1 )
  14.  
  15. #include <iostream>
  16. #include <new>
  17.  
  18. using namespace std;
  19.  
  20. int main(void){
  21.  
  22. int *T,*inc,h,i,n,a,c,count,u;
  23. long long int answer;
  24.  
  25. cin>>n>>c;
  26.  
  27. T=new int[2*n+4];
  28. inc=new int[2*n+4];
  29. for(i=0;i<2*n+4;i++)T[i]=0,inc[i]=0;
  30.  
  31. answer=0;
  32. count=0;
  33. for(i=1;i<=n;i++){
  34. cin>>a;
  35.  
  36. count+=(a>=c);
  37.  
  38. h=2*count-i+n;
  39. answer+=T[h];
  40.  
  41. T[h]++;// inc[h]=0 volt
  42. u=inc[h+1]+1;T[h+1]+=u;inc[h+1]=0;inc[h+2]+=u;// T[h+1] beállítása, most már h+1-ig minden T[] érték pontos
  43.  
  44. answer+=(count>=(i+1)/2); // egész sorozat eddig értékes-e
  45. }
  46.  
  47. cout<<answer<<endl;
  48. return 0;
  49. }
  50.  
Success #stdin #stdout 0s 3432KB
stdin
4 6
10 5 6 2
stdout
7