Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
分享一个自己写的树状数组求逆序数的O(nlogn)ac代码#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> #include<vector> using namespace std; int n,m; char s[110][60]; int c[60]; typedef pair<char,int>P; typedef pair<int,int>P1; int cmp(P p1,P p2) { return p1.first<p2.first; } int lowbit(int x) { return x&(x^(x-1)); } void add(int i,int x) { while(i<=n) { c[i]+=x; i+=lowbit(i); } } int Sum(int i) { int s=0; while(i>0) { s+=c[i]; i-=lowbit(i); } return s; } int Inversion(char * s) { memset(c,0,sizeof(c)); P p[60]; int cnt[60]={0}; int i; for(i=0;i<n;i++) { p[i+1].first=s[i]; p[i+1].second=i+1; } sort(p+1,p+1+n,cmp); int id=1; cnt[p[1].second]=id; for(i=2;i<=n;i++) //离散化 { if(p[i].first==p[i-1].first) cnt[p[i].second]=id; else cnt[p[i].second]=++id; } int sum=0; for(i=1;i<=n;i++) //插入 { add(cnt[i],1); //在离散化后的cnt[i]位置插入1 sum+=i-Sum(cnt[i]); } return sum; } class cmp1 { public: bool operator()(P1 &a,P1 &b)//按逆序对数从小到大输出,如数量一样,按原始下标输出。 { if(a.first!=b.first) return a.first>b.first; //first是逆序对数,second是输入的第几个字符串 return a.second>b.second; } }; int main() { // freopen("C:\\1.txt","r",stdin); cin>>n>>m; int i; priority_queue<P1,vector<P1>,cmp1>q; //最终输出的队列 for(i=1;i<=m;i++) { scanf("%s",s[i]); int num=Inversion(s[i]); //树状数组求逆序对数量 q.push(P1(num,i)); //入队列等待输出 } while(!q.empty()) { P1 x=q.top(); printf("%s\n",s[x.second]); q.pop(); } } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator