标签:style class code ons fir cas term nlog ref
Description
Input
Output
Sample Input
1 3 4 4 1 4 2 3 3 2 3 1
Sample Output
Test case 1: 5
思路:将k条path按path[i].x从小到大排序(若path[i].x相同,则按path[i].y从小到大排序),此时构成的path[1~k].y序列的逆序数便是答案;树状数组/归并排序求逆序数;
树状数组:https://www.cnblogs.com/hsd-/p/6139376.html
AC代码:
//树状数组求逆序数O(nlogn+logn) #include <iostream> #include<cstdio> #include<algorithm> #include<cstring> #define lowbit(x) x&(-x) typedef long long ll; using namespace std; struct Path{ int x,y; }path[1000010]; bool cmp(Path a,Path b){ if(a.x!=b.x) return a.x<b.x; else return a.y<b.y; } int n,m,k; int c[1010]; void add(int x,int val){ for(int i=x;i<=m;i+=lowbit(i)) c[i]+=val; } ll getsum(int x){ ll ret=0; for(int i=x;i>0;i-=lowbit(i)) ret+=c[i]; return ret; } int main() { int t; scanf("%d",&t); for(int s=1;s<=t;s++){ scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=k;i++) scanf("%d%d",&path[i].x,&path[i].y); sort(path+1,path+1+k,cmp); memset(c,0,sizeof(c)); ll ans=0; for(int i=1;i<=k;i++){ add(path[i].y,1);//出现过该数,则标记为1 ans+=(i-getsum(path[i].y));//前i的数里面大于path[i].y的数的个数等于i-前i个数里面小于等于path[i].y的数的个数(即getsum(path[i].y)) } printf("Test case %d: ",s); cout<<ans<<endl; } return 0; }
AC代码:
//归并排序求逆序数O(nlogn+nlogn) #include <iostream> #include<cstdio> #include<algorithm> typedef long long ll; using namespace std; struct Path{ int x,y; }path[1000010]; bool cmp(Path a,Path b){ if(a.x!=b.x) return a.x<b.x; else return a.y<b.y; } int n,m,k; int b[1000010]; int tmp[1000010]; ll ans=0; void merge_(int l,int m,int r){ int cnt=0; int i,j; for(i=l,j=m+1;i<=m&&j<=r;){ if(b[i]<=b[j]) {tmp[++cnt]=b[i]; i++;} else{ tmp[++cnt]=b[j]; j++; ans+=(m-i+1); } } while(i<=m) {tmp[++cnt]=b[i]; i++;} while(j<=r) {tmp[++cnt]=b[j]; j++;} for(int i=l,j=1;i<=r&&j<=cnt;i++,j++) b[i]=tmp[j]; } void merge_sort(int l,int r){ if(l==r) return; int m=(l+r)>>1; merge_sort(l,m); merge_sort(m+1,r); merge_(l,m,r); } int main() { int t; scanf("%d",&t); for(int s=1;s<=t;s++){ scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=k;i++) scanf("%d%d",&path[i].x,&path[i].y); sort(path+1,path+1+k,cmp); for(int i=1;i<=k;i++) b[i]=path[i].y; ans=0; merge_sort(1,k); printf("Test case %d: ",s); cout<<ans<<endl; } return 0; }
标签:style class code ons fir cas term nlog ref
原文地址:https://www.cnblogs.com/lllxq/p/9088928.html