Counting the algorithms
题目链接:点击打开链接
题目描述:在一个1到2*N的区间内,1到N这N个数都出现了两次,相同的数做差,做完之后删除,其他的元素位置也会被改变,所以用树状数组统计区间内的元素个数。加个位置数组快速找到相同数的位置。
代码如下:
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
#define MAXN 200005
int 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;
}