hoj 2430 Counting the algorithms(树状数组,贪心)

来源:互联网 发布:淘宝官网电话400 编辑:程序博客网 时间:2024/05/17 07:39

记录下第一次出现的位置和 两次出现位置的距离差,按照距离差降序排个序,然后扫一遍。。
我看网上别人做法扫一遍,再扫一遍,完事了,效率比我这要高。。。没想到这里写图片描述

#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;struct node{    int si,dis;};const int MAXN = 200020;node ns[MAXN/2];int cnt[MAXN];int N,num;bool cmp(const node& a, const node& b){    return a.dis > b.dis;}int lowBit(int x){    return x&-x;}int sum(int i){    int s = 0;    while(i > 0)    {        s += cnt[i];        i -= lowBit(i);    }    return s;}void add(int i, int x){    while(i <= N*2)    {        cnt[i] += x;        i += lowBit(i);    }}int main(){    while(scanf("%d",&N) != EOF)    {        memset(cnt,0,sizeof(cnt));        memset(ns,0,sizeof(ns));        for(int i = 1; i <= 2*N; ++i)        {            add(i,1);            scanf("%d",&num);            //记录每个数字第一次出现的下标和两个下标之间的差            if(ns[num].si == 0)                ns[num].si = i;            else                ns[num].dis = i-ns[num].si;        }        sort(ns+1,ns+1+N,cmp);        int res = 0;        for(int i = 1; i <= N; ++i)        {            res += sum(ns[i].si+ns[i].dis)-sum(ns[i].si);            add(ns[i].si,-1);            add(ns[i].si+ns[i].dis,-1);        }        printf("%d\n",res);    }    return 0;}
原创粉丝点击