hoj 2430 Counting the algorithms (树状数组)

来源:互联网 发布:android 查看端口占用 编辑:程序博客网 时间:2024/05/18 18:54

Counting the algorithms


题目链接:点击打开链接


题目描述:在一个1到2*N的区间内,1到N这N个数都出现了两次,相同的数做差,做完之后删除,其他的元素位置也会被改变,所以用树状数组统计区间内的元素个数。加个位置数组快速找到相同数的位置。


代码如下:

#include <cstring>#include <cstdio>#include <algorithm>using namespace std;#define MAXN 200005int n;int data[MAXN];int tree[MAXN];int vi[MAXN/2];int addre[MAXN/2];void add(int x,int num){    for(int i=x;i<=2*n;i+=i&-i)        tree[i]+=num;}int read(int x){    int sum=0;    for(int i=x;i>0;i-=i&-i)        sum+=tree[i];    return sum;}int main(){    int ans;    while(~scanf("%d",&n))    {        ans=0;        memset(tree,0,sizeof(tree));        memset(vi,0,sizeof(vi));        memset(addre,0,sizeof(addre));        for(int i=1;i<=2*n;i++)        {            add(i,1);            scanf("%d",&data[i]);            if(addre[data[i]]==0)                addre[data[i]]=i;        }        for(int i=2*n;i>0;i--)        {            if(vi[data[i]]==0)            {                int tem=read(i)-read(addre[data[i]]);          //   printf("%d  %d %d  %d \n",i,addre[data[i]],read(i),read(addre[data[i]]));                ans+=tem;                add(i,-1);add(addre[data[i]],-1);                vi[data[i]]==1;            }        }        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击