Beispiel #1
0
int main(int argc, char *argv[])
{
    setIO("sample");
    int n = gi;
    for(int i = 0;i<n;++i)
     a[i] = gi;
    int tn = 2*n;
    for(int i = 0;i<=tn;++i){
     double phie = (2*PI*double(i)/double(tn)); 
     powG[i] = ci(cos(phie),sin(phie));
    }
    fft(tn,a,0,b);
    for(int i = 0;i<=tn;++i,printf("\n"))
     printf("%.4f %.4f",real(b[i]),imag(b[i]));
    for(int i = 0;i<=tn;++i,endline())
     showci(powG[i]);
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #2
0
int main(int argc, char *argv[])
{
    setIO("sample");
    n = gi,m = gi;
    int all = 0;
    for(int i = 1;i<=n;++i)
     for(int j = 1;j<=m;++j){
      a[i][j] = gi; all += a[i][j];
      ++num;u[num].a = i;u[num].b = j;u[num].c = i*j;
     }
    sort(u+1,u+1+num);
    for(int i = 1;i<=num;++i)
    {
     if(all%u[i].c) continue;
     if(check(u[i])){ printf("%d\n",all/u[i].c);break;}
    }
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #3
0
int main(int argc, char *argv[])
{
    setIO("sample");
    n = gi,m=gi;
    for(int i = 1;i<=n;i++)
     a[i] = gi,p=max(p,a[i]+m+1);
    m++;
    int u = 0;
    for(int i = 1;i<=n;i++)
     for(int j = m;j>=1;j--)
     {
      int ans = getmax(a[i]+j,j);
      u = max(ans+1,u);
      change(a[i]+j,j,ans+1);
     }
    printf("%d\n",u);
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #4
0
int main(int argc, char *argv[])
{
    setIO("sample");
    int64 T =gi;
    while(T--)
    {
     n = gi; k = gi;flag = 0;
     for(int64 i = 1;i<=n;++i)
      for(int64 j = 1;j<=n;++j)
       m.a[i][j] = gi;
      mat a;
      PowM(a,k-1);
      int64 ans = 0;
      for(int64 i = 1;i<=n;++i)
       ans += a.a[i][i],ans%=mod;
      printf(I64D,ans);puts("");
    }
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #5
0
int main(int argc, char *argv[])
{
    setIO("sample");
    n=gi;a[n+1]=INF;
    for(int i = 1;i<=n;++i)
    {
     cin>>a[i];
     e[i] = (a[i-1]<a[i])?(e[i-1]+1):1;
     mx = max(mx,e[i]);
    }
    if(mx < n) ++ mx;
    for(int i = n;i;--i){
     s[i] = (a[i]<a[i+1])?(s[i+1]+1):1;
     if(a[i+1]-a[i-1]>1)
      mx = max(mx,e[i-1]+s[i+1]+1);
    }
    cout<<mx;
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #6
0
int main(int argc, char *argv[])
{
    setIO("sample");
    cin>>s;
    int l = s.length();
    for(int i = 0;i<l;++i){
     string tmp("");
     for(int j = 0;j<4 && i+j <l;++j){
     tmp += s[i+j];
     occ[tmp].pb(i);
     }
    }
    int q;
    cin>>q;
    while(q--){
     string a,b;
     cin>>a>>b;
     if(ans[MP(a,b)]) {
      cout<<ans[MP(a,b)]<<endl;
      continue;
     }
     vi va(occ[a]),vb(occ[b]);
     if(va.empty()||vb.empty()){
      ans[MP(a,b)]=-1;
      cout<<"-1"<<endl;
      continue;
     }
     int res = INF;
     vi::iter ia = va.begin(),ib = vb.begin();
     for(;ia!=va.end()&&ib!=vb.end();)
     {
      res = min(res,int(max(a.size()+*ia,b.size()+*ib)-min(*ia,*ib)));
      if(*ia < *ib)++ia;
      else ++ib;
     }
     cout<<res<<endl;
     ans[MP(a,b)] = res;
    }
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #7
0
int main(int argc, char *argv[])
{
    setIO("sample");
    n = gi;
    for(int i = 0;i<n;++i) scanf("%lf",&p[i]);
    sort(p,p+n);
    reverse(p,p+n);
    ld c0 = 1.0,c1 = 0.0;
    ld res  = -1.0;
    for(int i = 0;i<n;++i)
    {
     ld pl = p[i];
     c1 *= (1-pl);
     c1 += pl*c0;
     c0 *= (1-pl);
     res = max(res,c1);
    }
    printf("%.10f",res);
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #8
0
int main(int argc, char *argv[])
{
    setIO("sample");
    int t;t =gi;
    while(t--)
    {
     read<uint64>(n);
     uint64 p = n;
     uint64 e = n+1;
     while(!isprime<uint64>(p))
      p--;
     while(!isprime<uint64>(e))
      e++;
     uint64 ans1 = p*e-2*e+2*(n-p+1),ans2 = 2*p*e;
     uint64 tmp = gcd<uint64>(ans1,ans2);
     ans1/=tmp;ans2/=tmp;
     printf("%I64d/%I64d\n",ans1,ans2);
    }
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #9
0
int main(int argc, char *argv[])
{
    setIO("sample");
    int n , m , ans = 0;
    n = gi,m = gi;
    pow[0] = 1;
    for(int i = 0;i<n;++i)
     pow[i+1] = pow[i]*3,pre[i] = n;
    for(int i = 1;i<=m;++i){
     a[i] = gi;
     b[--a[i]] = i;
     if(i > 1)
      pre[a[i]] = a[i-1];
    }
    a[m+1] = n;
    f[0] = c[n] = 1;
    for(int i= 0;i<pow[n];++i)
     if(f[i]){
      int cnt = 0, k = 1,pos = 0 ;
      for(int j = d[0]=0,t=i;j<n;++j,t/=3)
       if(c[j] = t%3){
       ++cnt;
       if(b[j] > pos) pos = b[j];
       if(c[j] == 1 ) d[++d[0]] = j;
       }
       d[d[0]+1] = n;
       if(cnt == n) ans += f[i];
       for(int j = 0;j<n;++j)
        if(!c[j] && c[pre[j]]){
        bool t = true;
        for(;j>d[k];++k);
        for(int l = pos+1;t &&l<=m+1 && l <= k; ++l)
         if(a[l]> j) t = false;
        if(t) f[i+pow[j]+(k>d[0]?0:pow[d[k]])] += f[i];
        }
     }
    printf("%d",ans);
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #10
0
int main(int argc, char *argv[])
{
    setIO("sample");
    n = gi,k = gi;
    for(int i = 1;i<=n;++i)
     s[i] = gi;
    for(int i = 1;i<=n;++i) 
     s[i] += s[i-1];
    CLEAR(f,0xfe);
    f[0][0] = 0;
    for(int i = 1;i<=k;++i)
     for(int j = 1;j<=n;++j)
     {
      for(int u = 0;u<j;++u)
       if(f[j][i] < f[u][i-1]+(s[j]-s[u])*(s[n]-s[j])){
        f[j][i] = f[u][i-1]+(s[j]-s[u])*(s[n]-s[j]);
        g[j][i] = u;
       }
     }
    int ans=-INF,pos = 0;
    for(int i = 1;i<=n;++i)
      if(f[i][k] > ans)
      {
       ans = f[i][k];
       pos = i;
      }
    printf("%d\n",ans);
    int now = k;
    while(now)
    {
     ans2[now] = pos;
     pos = g[pos][now];
     --now;
    }
    for(int i = 1;i<=k;++i)
     printf("%d ",ans2[i]);
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #11
0
int main(int argc, char *argv[])
{
    setIO("sample");
    n = gi;int m=gi;
    for(int i = 1,u,v,w;i<=m;++i)u=gi,v=gi,w=gi,addedge(u,v,w);
    dj(1,ds,ss,qs);
    dj(n,dt,st,qt);
    for(int i = 1;i<n;++i)
     for(int j = hd[i];j;j=e[j].ne){
     int k = e[j].v;
      if(dt[k]+e[j].w == dt[i]){
       fa[i] = k,e[j].fl = true;
       addedge2(k,i);break;
      }
     }
    static int qu[MN],bot;
    qu[bot=1]=n;
    for(int i = 1;i<=bot;++i){
     int x = qu[i];
     for(int j = hd2[x];j;j=e2[j].ne) qu[++bot]=e2[j].v;
    }
    for(int i = 1;i<=bot;++i){
     int x = qu[i];
     if(ds[x]+dt[x] == ds[n]) prt[x] = x;
     else prt[x] = prt[fa[x]];
    }
    int ans = INF;
    for(int i = 1;i<=tot;++i){
     if(e[i].fl || ds[e[i].u]+e[i].w+dt[e[i].v]==ds[n])continue;
     int u = prt[e[i].u],v = prt[e[i].v];
     if(!u || !v || u==v || ds[u] > ds[v]) continue;
     int tmp = ds[e[i].u]+e[i].w+dt[e[i].v];
     ans = min(ans,tmp);
    }
    if(ans == INF )puts("-1");
    else printf("%d\n",ans);
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #12
0
int main(int argc, char *argv[])
{
    setIO("sample");
    int n , m;
    scanf("%d%d",&n,&m);
    for(int i = 1;i<=m;++i)
    {
     char opt[5];scanf("%s",opt);
     int x,y;scanf("%d%d",&x,&y);
     if(opt[0] == 'Q')
      if(t.isconnect(x,y))
       printf("Yes\n");
      else
       printf("No\n");
     if(opt[0] == 'C')
      t.link(x,y);
     if(opt[0] == 'D')
      t.cut(x,y);
    }
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #13
0
int main(int argc, char *argv[])
{
    setIO("sample");
    int n = gi,m = gi;
    mm[1] = phi[1] = K[1] = 1;
    for(int i = 2;i<=MN;++i){
     if(!mm[i])
     {
      mm[i] = i;phi[i] = i-1;
      K[i] = i;q[++top] = i;
     }
     for(int j = 1;j<=top && q[j]*i<=MN;++j)
     {
      int u = q[j]*i;
      mm[u] = q[j];
      phi[u] = phi[i];
      K[u] = K[i];
      if(i%q[j] == 0) {phi[u]*=q[j];break;}
      phi[u]*=(q[j]-1);
      K[u]*=q[j];
     }
    }
  
    for(int i = 1;i<=n;++i)
     for(int j = i;j<=n;j+=i)
      yueshu[j].pb(i);
    int now = 0;
    for(int i = 1;i<=MN;++i)
    {
     update(now,phi[i]);
     S[1][i] = now;
    }
    int ans = 0;
    for(int i = 1;i<=n;++i)
     update(ans,calc(i,m));
    printf("%d\n",ans);
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #14
0
int main(int argc, char *argv[])
{
    setIO("sample");
    for(int i = 0;i<2;++i) f[i].clear();
    scanf("%d%d",&n,&m);
    for(int i = 1;i<=n;++i)
     for(int j = 1;j<=m;++j)
      scanf("%lf",&a[i][j]);
    f[0][MP(MP(0,0),1)] = 1;
    for(int i = 1;i<=n;++i)
    {
     int now = i&1,last = now^1;
     f[now].clear();
     for(itor it = f[last].begin();it != f[last].end();++it)
     {
      int col = (*it).X.X.X,len = (*it).X.X.Y,len1 = (*it).X.Y;
      double pp = (*it).Y;
      for(int j = 1;j<=m;++j)
      {
       if(j != col)
       f[now][MP(MP(j,1),len1)] += pp*a[i][j];
       else
       f[now][MP(MP(j,len+1),max(len1,len+1))] += pp*a[i][j];
      }
     }
    }
    double ans = 0;
    int ECase = 0;
    for(itor it = f[(n)&1].begin();it != f[(n)&1].end();++it)
    {
     //++ECase;
     //ff(debug,"number %d : col:%d len:%d len1:%d P:%.5f\n",ECase,(*it).X.X.X,(*it).X.X.Y,(*it).X.Y,(*it).Y);
     ans += (*it).Y*double((*it).X.Y);
    }
    printf("%.6f\n",ans);
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #15
0
int main(int argc, char *argv[])
{
    setIO("sample");
    n = gi;
    for(int i = 1;i<=n;++i) a[i].Y = gi,sou[i] = i;
    for(int i = 1;i<=n;++i) a[i].X = gi;
    sort(sou+1,sou+1+n,cmp2);
    sort(a+1,a+n+1,cmp1);
    stk[++top] = 1;
    for(int i = 2;i<=n;++i)
    {
      if(dblcmp(a[stk[top]].X-a[i].X) == 0) continue;
      while(top)
      {
       pdd pu = inser(stk[top],i);
       if(pu.X<0) --top;
       else if(top >= 2 && pu.Y<getv(stk[top-1],pu.X)) --top;
       else break;
      }
      stk[++top] = i;
    }
    for(int i = 1;i<=top;++i)
    {
     int x = stk[i];
     for(int j = x;j<=n;++j)
      if(dblcmp(a[j].X - a[x].X) != 0 || dblcmp(a[j].Y - a[x].Y) != 0)
       break;
      else
       ans.pb(sou[j]);
    }
    sort(ans.begin(),ans.end());
    printf("%d\n",ans.size());
    for(int i = 0;i<ans.size()-1;++i)
     printf("%d ",ans[i]);
    printf("%d\n",ans[ans.size()-1]);
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #16
0
int main(int argc, char *argv[])
{
    setIO("sample");
    n = gi,build(1,1,n),m = gi;
    while(m--) {
    type = gi,x = gi,y = gi;
     if(type){
       k = gi; int len = 0,ans = 0;
       while(len < k){
        query(1,1,n,x,y,o[++len]);
        if(o[len].a[1].m <= 0) {--len;break;}
        ans += o[len].a[1].m;
        rev(1,1,n,o[len].a[1].L,o[len].a[1].R);
       }
       printf("%d\n",ans);
       for(int i = len;i;--i)
        rev(1,1,n,o[i].a[1].L,o[i].a[1].R);
     }
     else modify(1,1,n,x,y);
    }  
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #17
0
int main(int argc, char *argv[])
{
    srand(233);
    setIO("sample");
    n = gi; m = gi; q = gi;
    for(int i = 1;i<=n;++i) mp[i] = ((rand())*p+pp*(rand()+ppp))*pppp;
    size[1] = n;
    for(int i = 1;i<=n;++i) room[1] ^= mp[i],bel[i] = 1;
    s.insert(1);
    while(q--)
    {
     char opt[3];scanf("%s",opt);
     if(opt[0] == 'C'){
      int i = gi,j= gi;
      Change(i,j);
     }else {
      int l = gi,r = gi;
      printf("%d\n",Qsum(l,r));
     }
    }
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #18
0
int main(int argc, char *argv[])
{
    setIO("QTREE7");
    scanf("%d",&n);
    t[1].init(n);t[0].init(n);
    for(int i = 1,x,y;i<=n-1;++i)
    {
     scanf("%d%d",&x,&y);
     ae(x,y);ae(y,x);
    }
    for(int i = 1;i<=n;++i)
     scanf("%d",&col[i]);
    for(int i = 1;i<=n;++i)
     scanf("%d",&we[i]);
    bfs(1);
    scanf("%d",&m);
    for(int i = 1,x,y,z;i<=m;i++)
    {
     scanf("%d%d",&x,&y);
     if(x == 0)
      printf("%d\n",t[col[y]].query(y));
     else if(x == 1)
     {
      t[col[y]].cut(y);
      col[y]^=1;
      t[col[y]].link(y);
     }
     else if(x == 2)
     {
     scanf("%d",&z);
     t[0].modify(y,z);
     t[1].modify(y,z);
     }
    }
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #19
0
int main(int argc, char *argv[])
{
    setIO("sample");
    srand(19961028);
    n = gi,m = gi;
    for(int i = 1;i<=n;++i) a[i] = NULL;
    init();
    while(m--){
     char tp = getchar();
     while(tp != 'C' && tp != 'Q') tp = getchar();
     if(tp == 'C')
     {
      int l= gi,r = gi,k = gi;
      change(l,r,k);
     }
     else if(tp == 'Q')
     {
      int l = gi,r = gi;
      printf("%d\n",query(l,r));
     }
    }
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #20
0
int main(int argc, char *argv[])
{
    setIO("sample");CLEAR(st,0xff);
    n = gi;
    for(int i = 1;i<=n;fa[i]=i,++i) a[i] = gi,b[i] = a[i];
    sort(b+1,b+1+n);
    int l = unique(b+1,b+1+n)-b-1;
    for(int i = 1;i<=n;++i) a[i] = lower_bound(b+1,b+l+1,a[i])-b;
    a[0] = -INF,a[n+1] = -INF;
    for(int i = 0;i<=n+1;++i)
    {
     while(top && a[stk[top]]>a[i]) rm[stk[top]]=i,--top;
     ++top;stk[top] = i;
    }
    top = 0;
    for(int i = n+1;i>=0;--i)
    {
     while(top && a[stk[top]]>a[i]) lm[stk[top]]=i, --top;

     ++top;stk[top] = i;
    }
    top = 0;
    for(int i = 1;i<=n;++i)
     add(lm[i]+1,rm[i]-1,0,i);
    for(int i = 1;i<=n;++i){
     while(top && a[stk[top]] <= a[i]) unions(i,stk[top]),--top;
     ++top; stk[top] = i;
     TRA(x,i) 
     ans[lk[x].w] = a[gf(lk[x].v)];
    }
    for(int i = 1;i<=n;++i)
     printf(i==1?"%d":" %d",b[ans[i]]-b[a[i]]);
    puts(" ");
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #21
0
int main(int argc, char *argv[])
{
    setIO("sample");
    n = gi;
    if(n % 2 == 0){
          printf("NOT POSSIBLE\n");closeIO();return 0;
    }
    bool unique = true;
    scanf("%s",a+1);
    pow[0].v = 1;
    for(int i = 0;i<=n;++i)
     pow[i+1] = pow[i]*int65(p);
    for(int i = 1;i<=n;++i) pre[i] = (pre[i-1]*int65(p)+int65(a[i]));
    b[0] = pre[n/2];
    b[1] = (pre[n]-((pre[n/2+1])*(pow[n/2])));
    int ans = 0;
    if(b[0] ==b[1]){printf("%s",&a[n/2+2]); closeIO();return 0;}
    for(int i = 1;i<=n/2;++i)
     if(getnew(1,i-1)*pow[n/2-i+1]+getnew(i+1,n/2+1)==b[1])
      ans = ans? (unique = false):i;
    for(int i = n/2+2;i<=n;++i)
     if(getnew(n/2+1,i-1)*pow[n-i]+getnew(i+1,n) == b[0])
      ans = ans? (unique = false):i;
    if(unique){
     if(ans == 0)
      printf("NOT POSSIBLE");
     else if(ans <= n/2+1)
      printf("%s",&a[n/2+2]);
     else 
      for(int i = 1;i<=n/2;++i) printf("%c",a[i]);
     puts("");
    }
    else printf("NOT UNIQUE\n");
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #22
0
int main(int argc, char *argv[])
{
    setIO("sample");
    n = gi;
    l = n;
    for(int i = 1; i<=n-1; ++i)
    {
        int x = gi,y = gi;
        add(x,y);
        add(y,x);
    }
    CLEAR(f,1);
    CLEAR(son,0);
    CLEAR(deep,0);
    f[1] = false,tim = 0,deep[1] = 1;
    dfs(1);
    tot = 0;
    int tmp = build(0,1,n);
    for(int i = 1; i<=n; ++i) c[i] = tmp;
    m = gi;
    for(int i = 1; i<=m; ++i)
    {
        int x = gi,y = gi;
        ins(point[x],point[y],1);
        ins(point[y],point[x],1);
    }
    int count = gi;
    while(count--)
    {
        int opt = gi,x= gi,y=gi;
        if(opt == 1)
        {
            ins(point[x],point[y],1);
            ins(point[y],point[x],1);
        }
        if(opt == 2)
        {
            ins(point[x],point[y],-1);
            ins(point[y],point[x],-1);
        }
        if(opt == 3)
        {
            if(point[x]>point[y]) swap(x,y);
            if(point[x]+son[x]-1>=point[y]) //case 1:y belongs to x
            {
                tmp = lca(x,y);
                int x1,x2,y1,y2;
                x1 = point[tmp]-1;
                x2 = point[tmp]+son[tmp];
                y1 = point[y];
                y2 = y1 + son[y]-1;
                printf("%d\n",getsum(y2,1,x1)-getsum(y1-1,1,x1)+getsum(y2,x2,n)-getsum(y1-1,x2,n));
            }
            else { //case 2:y not belongs to x
                int x1,x2,y1,y2;
                x1 = point[x];
                x2 = x1 + son[x]-1;
                y1 = point[y];
                y2 = y1 + son[y]-1;
                printf("%d\n",getsum(y2,x1,x2)-getsum(y1-1,x1,x2));
            }
        }
    }
    closeIO();
    return EXIT_SUCCESS;
}
Beispiel #23
0
int main( int argc, char * argv[ ] )
{
  // start timer
  const double t_0 = omp_get_wtime( );

  const unsigned int dim   = 3;  
  const unsigned int order = DFMM_ORDER;
  const double eps         = DFMM_EPSILON;

  typedef DimTraits<dim>::point_type point_type;
  typedef Dof<dim>                particle_type;

  // required command line arguments
#ifdef DFMM_USE_OMP
  if (argc != 5) {
#else
  if (argc != 4) {
#endif
    std::cerr << "Wrong number of command line arguments" << std::endl;
    exit(-1);
  }
  const std::string filename(    argv[1]);
  const unsigned long N   = atoi(argv[2]);
  const unsigned int lmax = atoi(argv[3]);

#ifdef DFMM_USE_OMP
  const unsigned int nthreads = atoi(argv[4]);
  omp_set_num_threads(nthreads);
  std::cout << "Using " << omp_get_max_threads() << " threads." << std::endl;
#endif

  particle_type *const particles = new particle_type [N];
  unsigned int  *const pindices  = new unsigned int  [N];
  ReadParticles(filename, N, particles);

  // fill pindices
  for (unsigned int p=0; p<N; ++p)
    pindices[p] = particles[p].getId();

  // plot particles
  //Plot<particle_type> plotter(particles, N);
  //plotter.plot();

  // get bounding box of root cluster
  const std::pair<point_type,point_type> bbx = GetBoundingBox(particles, N);

  // storage: setup and stores level infos, stores kernel wrapper, etc.
  typedef Storage<dim> storage_type;
  storage_type storage(bbx, lmax);


  // setup root cluster
  typedef Cluster<dim> cluster_type;
  cluster_type* cl = new cluster_type(N, storage.getRootClusterCenter());
  
  // subdivide root cluster, then generated level based cluster lists
  std::vector<std::vector<cluster_type*> > all_cluster_vectors;
  const unsigned int ncl = cl->subdivide(storage.getLevels(),
                                         all_cluster_vectors,
                                         particles, pindices, lmax);
  std::cout << "\n- Number of clusters " << ncl << std::endl;

  // check if particles are in correct cluster
  AreParticlesInCluster<particle_type> areThey(particles,pindices);
  bool all_particles_are_in_cluster = true;
  BOOST_FOREACH(const cluster_type *const lcl, all_cluster_vectors.back())
    if (!areThey(lcl, storage.getLevels().at(lcl->getNlevel()))) {
      std::cout << "Particles are not in cluster they belong to." << std::endl;
      all_particles_are_in_cluster = false;
    }
  assert(all_particles_are_in_cluster);



  // LAPLACE
  typedef KernelFunction<LAPLACE3D> kernel_type;
  typedef kernel_type::value_type value_type;
  kernel_type kernel;
  storage.initLevels();



  //typedef M2LHandlerSArcmp<dim,order,value_type> m2l_handler_type;
  //typedef M2LHandlerNA<dim,order,value_type> m2l_handler_type;
  //typedef M2LHandlerNAsym<dim,order,value_type> m2l_handler_type;
  //typedef M2LHandlerNAblk<dim,order,value_type> m2l_handler_type;
  //typedef M2LHandlerIA<dim,order,value_type> m2l_handler_type;
  typedef M2LHandlerIAsym<dim,order,value_type> m2l_handler_type;
  //typedef M2LHandlerIAblk<dim,order,value_type> m2l_handler_type;


  // init m2l handler 
  typedef std::vector<m2l_handler_type> m2l_handler_type_vector;
  m2l_handler_type_vector all_m2l_handler;
  storage.initialize(all_m2l_handler);
  m2l_handler_type::getInfo();




  // cluster bases
  typedef ClusterBasis<dim,order,value_type> clusterbasis_type;
  std::vector<clusterbasis_type> rbasis(ncl), cbasis(ncl);

  // cluster expansions
  typedef ExpansionHandler<dim,order,value_type> expansion_type;
  std::vector<expansion_type> rexph(ncl), cexph(ncl);
  
  // cluster relations
  typedef Relations<dim> relations_type;
  std::vector<relations_type> relations(ncl);

  // setup multilevel relations
  SetupClusterRelations(all_cluster_vectors, rexph,
                        all_cluster_vectors, cexph, 
                        relations, storage.getLevels(), all_m2l_handler);


  // write out info
  storage.writeInfo(all_m2l_handler);


  ////////////////////////////////////////////////////////////////////
  // draw cross section through cluster oct-tree at "loc" in direction "dir"
  point_type loc;
  for (unsigned int i=0; i<dim; ++i)
    loc[i] = (bbx.first[i]+bbx.second[i]) / 2;
  std::cout << "\n- Center of particles at " << loc << std::endl;
  std::cout << " - a = " << bbx.first << "\tb = " << bbx.second << std::endl;
  
  //  std::cout << "\n- Origin of PS pictures at " << loc << std::endl;
  
  //const unsigned int dir0 = 0;
  //drawCrossSection(filename, loc, dir0, 
  //                 storage.getRootClusterCenter(),
  //                 storage.getRootClusterExtension(),
  //                 all_cluster_vectors, storage.getLevels(), all_m2l_handler);
  //
  //const unsigned int dir1 = 1;
  //drawCrossSection(filename, loc, dir1, 
  //                 storage.getRootClusterCenter(),
  //                 storage.getRootClusterExtension(),
  //                 all_cluster_vectors, storage.getLevels(), all_m2l_handler);
  //
  //const unsigned int dir2 = 2;
  //drawCrossSection(filename, loc, dir2, 
  //                 storage.getRootClusterCenter(),
  //                 storage.getRootClusterExtension(),
  //                 all_cluster_vectors, storage.getLevels(), all_m2l_handler);
  //////////////////////////////////////////////////////////////////////



  // compute m2l operators
  ComputeM2Loperators(all_m2l_handler, kernel, eps);



  // l2l/m2m operators
  std::cout << "\n- Evaluating interpolation operators " << std::flush;
  const double t_io = omp_get_wtime();
  setIO(all_cluster_vectors, rbasis, all_m2l_handler, pindices, particles);
  setIO(all_cluster_vectors, cbasis, all_m2l_handler, pindices, particles);
  std::cout << " took " << omp_get_wtime() - t_io << " s" << std::endl;



  // densities and potentials
  value_type *const y = new value_type [N];
  for (unsigned int n=0; n<N; ++n)
    y[n] = (double)rand()/(double)RAND_MAX;
  value_type *const x = new value_type [N];
  for (unsigned int n=0; n<N; ++n) x[n] = 0.;





  // m2m
  std::cout << "\n- Applying M2M operators\n" << std::flush;
  const double t_m2m = omp_get_wtime();
  ApplyM2Moperators(all_cluster_vectors, cbasis, cexph, all_m2l_handler, y);
  std::cout << "  - overall " << omp_get_wtime() - t_m2m << " s" << std::endl;

  // m2l
  std::cout << "\n- Applying M2L operators\n" << std::flush;
  const double t_m2l = omp_get_wtime();
  ApplyM2Loperators(all_cluster_vectors, rexph, cexph, relations,
                    all_m2l_handler);
  std::cout << "  - overall " << omp_get_wtime() - t_m2l << " s" << std::endl;

  // l2l
  std::cout << "\n- Applying L2L operators\n" << std::flush;
  const double t_l2l = omp_get_wtime();
  ApplyL2Loperators(all_cluster_vectors, rbasis, rexph, all_m2l_handler, x);
  std::cout << "  - overall " << omp_get_wtime() - t_l2l << " s" << std::endl;

  // apply near field on the fly
  typedef NFadder<cluster_type,particle_type,relations_type,kernel_type>
    nfc_type;
  ApplyNearField(all_cluster_vectors.back(),
                 nfc_type(kernel, relations,
                          pindices, particles,
                          pindices, particles,
                          x, y));



//  std::cout << "\n- Size of value_type is " << sizeof(value_type)
//            << " byte." << std::endl;
//
//  // direct calculation
//  const long size = ndofs*ndofs;
//  const long size_in_bytes = size * sizeof(value_type);
//  const double mem_dns = (long)size_in_bytes / (1024.*1024.);
//  std::cout << "\n- Direct calculation of " << ndofs << " times " << ndofs
//            << " particles requires " 
//            << (long)size_in_bytes / (1024.*1024.)
//            << " Mb."<< std::endl;
//  const double t_direct = omp_get_wtime();
//  value_type *const x0 = new value_type [ndofs];
//  blas::setzero(ndofs, x0);
//  std::cout << " - Memory allocation " << std::flush;
//  const double t_alloc = omp_get_wtime();
//  value_type *const K = new value_type [ndofs * ndofs];
//  const double t_calc = omp_get_wtime();
//  std::cout << "took " << t_calc - t_alloc << " s" << std::endl;
//  std::cout << " - Matrix evaluation " << std::flush;
//  storage.getFundSol().compute(ndofs, dofs, ndofs, dofs, K);
//  const double t_matvec = omp_get_wtime();
//  std::cout << "took " << t_matvec - t_calc << " s" << std::endl;
//  // matrix vector product
//  std::cout << " - Matrix vector multiplication " << std::flush;
//  blas::gemva(ndofs, ndofs, 1., K, y, x0);
//  std::cout << "took " << omp_get_wtime() - t_matvec << " s" << std::endl;
//  std::cout << "  took " << omp_get_wtime() - t_direct << " s" << std::endl;


  
  // exact clusterX
  std::cout << "\n- Exact evaluation of cluster X " << std::flush;
  const double t_ex = omp_get_wtime();
  cluster_type *const clx = all_cluster_vectors.back().front();
  assert(clx->getNbeg() == 0);
  const unsigned int nx = clx->getSize();
  const unsigned int ny = N;
  value_type *const x0 = new value_type [nx];
  blas::setzero(nx, x0);
  for (unsigned int i=0; i<nx; ++i)
    for (unsigned int j=nx; j<ny; ++j)
      x0[i] += kernel(particles[pindices[i]].getPoint(),
                      particles[pindices[j]].getPoint()) * y[j];
  std::cout << "took " << omp_get_wtime() - t_ex << " s" << std::endl;


//  value_type sum_x  = 0;
//  value_type sum_x0 = 0;
//  for (unsigned int n=0; n<nx; ++n) {
//    sum_x  += x[ n];
//    sum_x0 += x0[n];
//  }
//  std::cout << "\nSize of cluster X = " << nx
//            << "\tsumx = " << sum_x
//            << "\tsumx0 = " << sum_x0 << std::endl;
//  for (unsigned int n=0; n<(10<nx?10:nx); ++n)
//    std::cout << x[n] << "\t" << x0[n] << "\t" << x[n]-x0[n] << std::endl;
  
  std::cout << "\n- L2  error " << computeL2norm( nx, x0, x) << std::endl;
  std::cout <<   "- Inf error " << computeINFnorm(nx, x0, x) << std::endl;

  std::cout << "\n- INTERPOLATION_ORDER = " << order
            << "\n- EPSILON = " << eps << std::endl;



  // clear memory
  delete [] x;
  delete [] y;
  delete [] x0;

  delete cl;
  delete [] particles;                         
  delete [] pindices;
  


  ////////////////////////////////////////////////////
  std::cout << "\n- Overall time " << omp_get_wtime( ) - t_0
            << " s" << std::endl;
  ////////////////////////////////////////////////////


  return 0;
}