zafu 1464 树状数组

http://info.zjfc.edu.cn/acm/problemDetail.aspx?pid=1464

 

A String Problem

时间限制 : 1000 ms    内存限制 : 32 MB

提交次数 : 105    通过次数 : 22

题目描述

有N个由小写字母构成的单词。问,在第i个单词前面,字典序比第i个单词不大于的单词有几个
?什么是字典序,就是单词在英语字典中出现的顺序,这个应该不用过多解释吧?举个例子,
zhangzhen的字典序比zhangjinglei大,因为在字典中,zhangzhen这个单词出现在zhangjinglei
后面(假设存在这两个单词)。

输入描述

第一行一个整数N(1≤N≤100000) ,代表字符串个数。接下来N行(也就是从第2行到第N+1行),
第i行表示字符串S[i-1],字符串长度不大于25, 且都由小写字母构成。

输出描述

输出一行, 有N个整数,a[1]...a[N],a[i]表示存在S[j]字典序不大于S[i](j<i)的个数。每两个数字之间以空格符隔开

样例输入

5
e
d
c
b
a

样例输出

0 0 0 0 0

作者

Zhang Zhen

来源

浙江农林大学第十届电脑节程序设计大赛正式赛

 

/*

	校赛时YY为字典树,之后大牛告知是树状数组,顿时惊呼“帅”

	

	变形为树状数组

	lowbit(x) :flag[i]的值应该是   ( i&(-i),i] , 左开右闭



	WA十次的错点:排序时,判断两字符串相等时,应再考虑位置的大小,

	              反复置换排序后同一个字符串可以大的在前面,小的在后面

				(感谢DSH帮找出)



	后记:于DSH大神的代码相比,我的太烂了,该学学C++(即便还学校没交),

	      C确实不如C++方便,而且C++更帅一点 ·_·

*/





#include <stdio.h>

#include <string.h>

#include <algorithm>

using namespace std;

struct ccc

{

	int num;

	char c[30];

}s[100005];

int flag[100005],n;

bool cmp(struct ccc a,struct ccc b)

{

	int t=strcmp(a.c,b.c);

	if(t==0)	return a.num < b.num;//!!!!!!!!!!!!!!!!!!!!!!

	else return t<0;

}

int SUM(int x)

{

	int ss=0,i;

	for(i=x;i<n;i+=(i&(-i)))// 经跟

		flag[i]++;

	for(i=x-1;i>0;i-=(i&(-i)))

		ss += flag[i];

	return ss;

}



int main()

{

	int i,j;

	int a[100005];

	scanf("%d",&n);

	for(i=1;i<=n;i++)

	{

		scanf("%s",s[i].c);

		s[i].num=i;

	}

	//

	sort(s + 1,s + n + 1,cmp);

	for(i=1;i<=n;i++)

	{

		a[s[i].num]=SUM(s[i].num );

	}

	//

	for(i=1;i<n;i++)

	{

		printf("%d ",a[i]);

	}

	printf("%d\n",a[n]);	

	return 0;

}

你可能感兴趣的:(树状数组)