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
来源
浙江农林大学第十届电脑节程序设计大赛正式赛
/* 校赛时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; }