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;
}
posted @ 2010-11-30 22:06  kfinder  阅读(203)  评论(0编辑  收藏  举报