POJ3067 Japan

树状数组基础

View Code
//11584687    NKHelloWorld    3067    Accepted    2764K    485MS    C++    1186B    2013-05-11 14:37:10
//这道题可能存在重边,K可能很大,需要longlong才能过
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
int n,m,k;
ll tree[1100];
struct NODE
{
    int x,y;
}node[1000*1000];

bool cmp(NODE n1,NODE n2)
{
    if(n1.x == n2.x)
    {
        return n1.y < n2.y;
    }
    return n1.x < n2.x;
}

ll sum(int pos)
{
    ll ret = 0;
    while(pos > 0)
    {
        ret += tree[pos];
        pos -= (pos & -pos);
    }
    return ret;
}

void BITinsert(int pos ,int val)
{
    while(pos <= 1000)
    {
        tree[pos] += val;
        pos += (pos & -pos);
    }
}

int main()
{
    int T;
    scanf("%d",&T);
    for(int TT = 1; TT<=T;TT++)
    {
        memset(tree,0,sizeof(tree));
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<k;i++)
        {
            scanf("%d%d",&node[i].x,&node[i].y);
        }
        sort(node,node+k,cmp);

        ll ans = 0;
        for(int i=k-1;i>=0;i--)
        {
            if(node[i].y != 1)
            {
                ans += sum(node[i].y-1);
            }
            BITinsert(node[i].y,1);
        }

        printf("Test case %d: %lld\n",TT,ans);
    }
    return 0;
}

POJ2299 Ultra-QuickSort

离散化+树状数组求逆序数

View Code
//11585027    NKHelloWorld    2299    Accepted    9452K    672MS    C++    1224B    2013-05-11 15:54:12
//离散化+树状数组求逆序数
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;

int maxval;
int a[510000];
ll c[510000];

ll bit_sum(int pos)
{
    ll ret = 0;
    while(pos >= 1)
    {
        ret += c[pos];
        pos -= (pos & -pos);
    }
    return ret;
}

void bit_insert(int pos,int det)
{
    while(pos <= maxval)
    {
        c[pos] += det;
        pos += (pos & -pos);
    }
}

struct NODE
{
    int val,pos;
}node[510000];



bool cmp(NODE a,NODE b)
{
    return a.val < b.val;
}

int main()
{
    int n;
    while(scanf("%d",&n), n!=0)
    {
        memset(c,0,sizeof(c));
        maxval = n;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&node[i].val);
            node[i].pos = i;
        }
        sort(node+1,node+n+1,cmp);
        for(int i=1;i<=n;i++)
        {
            a[node[i].pos] = i;
        }

        //for(int i=1;i<=n;i++)printf("%d ",a[i]);printf("\n");
        ll ans = 0;
        for(int i=n;i>=1;i--)
        {
            //printf("i:%d %d\n",i,bit_sum(a[i]));
            ans += bit_sum(a[i]);
            bit_insert(a[i],1);
        }
        printf("%lld\n",ans);
    }
}

 归并排序求逆序

View Code
//11585216    NKHelloWorld    2299    Accepted    3688K    375MS    C++    921B    2013-05-11 16:28:45
//归并排序法求逆序数
//加输入外挂后C++600ms,g++157ms
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;

int a[510000];
int t[510000];

ll merge_sort(int l,int r)
{
    ll ans = 0;
    int i,j,p=l,m=(l+r)/2;
    if(l==r)    return 0;
    ans += merge_sort(l,m);
    ans += merge_sort(m+1,r);
    for(i=l,j=m+1; i<=m && j<= r;)
    {
        if(a[i] > a[j])
        {
            t[p++] = a[j++];
            ans += m - i + 1;
        }
        else
        {
            t[p++] = a[i++];
        }
    }
    while(i <= m)   t[p++] = a[i++];
    while(j <= r)   t[p++] = a[j++];

    for(i=l;i<=r;i++)
    {
        a[i] = t[i];
    }

    return ans;
}
inline void scan(int &n)
{
    char c;
    //while(c=getchar(),c<'0'||c>'9');
    n=0;
    while(c=getchar(),c<='9'&&c>='0')
        n=n*10+c-'0';
}

int main()
{
    int n;
    while(scanf("%d",&n), n!=0)
    {
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        ll ans = merge_sort(0,n-1);

        printf("%lld\n",ans);
    }
}

 

posted on 2013-05-11 16:34  NKHe!!oWor!d  阅读(156)  评论(0编辑  收藏  举报