Cod sursa(job #1800854)

Utilizator touristGennady Korotkevich tourist Data 8 noiembrie 2016 10:54:37
Problema Combinari Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.38 kb
#include <bits/stdc++.h>
#define Nmax 100005
#define SQRT 325

using namespace std;

int a[Nmax],n,m,s[Nmax],v[Nmax],l,p[Nmax];
int le[Nmax],ri[Nmax],cnt[SQRT][SQRT],lft[Nmax],rgt[Nmax];
long long s1[Nmax],ans[Nmax],d[SQRT][SQRT],sum[SQRT][SQRT];

inline bool Cmp(const int A, const int B)
{
    return a[A]<a[B];
}

inline int Sum(int x, int y)
{
    return s[y]-s[x-1];
}

inline long long Sum1(int x, int y)
{
    return s1[y]-s1[x-1];
}

int main()
{
    int i,j,k,Sqrt;
    #ifndef ONLINE_JUDGE
        freopen ("date.in","r",stdin);
        freopen ("date.out","w",stdout);
    #endif
    cin>>n>>m;
    for(i=1;i<=n;++i) cin>>a[i];
    for(i=1;i<=m;++i) cin>>le[i]>>ri[i];
    for(i=1;i<=n;++i) p[i]=i;
    sort(p+1,p+n+1,Cmp);
    Sqrt=sqrt(n);
    for(i=1;i<=n;i+=Sqrt)
    {
        int st=i,dr=min(i+Sqrt-1,n);

        for(j=1;j<=n;++j) s[j]=s1[j]=0;
        for(j=1;j<st;++j) ++s[p[j]];
        for(j=1;j<=n;++j) s[j]+=s[j-1];
        for(j=st;j<=dr;++j) s1[p[j]]+=a[p[j]];
        for(j=1;j<=n;++j) s1[j]+=s1[j-1];
        for(j=1;j<=m;++j) ans[j]+=1LL*Sum(le[j],ri[j])*Sum1(le[j],ri[j]);

        for(j=st,l=0;j<=dr;++j) v[++l]=p[j];
        sort(v+1,v+l+1);

        for(j=1;j<=l;++j)
        {
            cnt[j][j]=1;
            for(k=j-1;k;--k)
                cnt[k][j]=cnt[k+1][j]+(a[p[j]]>=a[p[k]]);
        }

        for(j=1;j<=l;++j)
            for(k=j-1;k;--k)
                sum[k][j]=sum[k+1][j]+1LL*(a[p[j]]<a[p[k]])*a[p[k]];

        for(k=1;k<=l;++k)
            for(j=k;j<=l;++j)
                d[k][j]=d[k][j-1]+1LL*cnt[k][j]*a[p[j]]+sum[k][j];

        cout<<d[1][1]<<"\n";

        int poz=1;
        for(k=1;k<=n;++k)
        {
            lft[k]=lft[k-1];
            if(p[poz]==k)
            {
                lft[k]=k; ++poz;
            }
        }

        poz=l;
        for(k=n;k;--k)
        {
            rgt[k]=rgt[k+1];
            if(p[poz]==k)
            {
                rgt[k]=k; --poz;
            }
        }

        for(j=1;j<=m;++j)
        {
            int st=rgt[le[j]],dr=lft[ri[j]];
            cout<<st<<" "<<dr<<"\n";
            ans[j]+=d[st][dr];
        }
    }
    cout<<setprecision(10)<<fixed;
    //for(i=1;i<=m;++i) cout<<(long double)ans[i]/(1LL*(ri[i]-le[i]+1)*(ri[i]-le[i]+1))<<"\n";
    for(i=1;i<=m;++i) cout<<(long double)ans[i]<<"\n";
    return 0;
}