(1)用结构体存每个数的数置和它的值,struct cnode{int value,int pos};
(2)pos位置取负再加上MAXN+1,MAXN(是元素位置的最大值),
(3)排序:先按value从小到大排,再按pos从小到大排,剩下的就是求每个元素左下角的元素个数,交给树状数组来处理是再好不过的事了。
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int MAXN=500000; struct cnode { int pos; int value; }node[MAXN+10]; int tree[MAXN+10]; bool cmp(const cnode &e1,const cnode &e2) { if(e1.value!=e2.value) { return e1.value<e2.value? true:false; } else { return e1.pos<e2.pos? true:false; } } int n; int sum(int x) { int value=0; while(x>0) { value+=tree[x]; x-=(x&(-x)); } return value; } void insert(int x) { while(x<=MAXN) { tree[x]++; x+=(x&(-x)); } } int main() { //int t; //freopen("tree.out","w",stdout); // freopen("1804.in","r",stdin); // scanf("%d",&t); int num[MAXN+10]; int sub; int i; int Case=0; // while(t--) // { while(scanf("%d",&n)!=EOF) { if(n==0) { break; } memset(tree,0,sizeof(tree)); Case++; // scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&num[i]); } sub=1; for(i=n;i>0;i--) { node[sub].pos=-i+MAXN+1; node[sub].value=num[i]; sub++; } sort(&node[1],&node[n+1],cmp); long long ans=0; int samenum=0; node[0].value=-1000000-1; for(i=1;i<=n;i++) { if(node[i].value!=node[i-1].value) { samenum=0; ans+=sum(node[i].pos-1); //insert(node[i].pos); //ans+=beforevalue; } else { samenum++; ans+=sum(node[i].pos-1)-samenum; // insert(node[i].pos); } insert(node[i].pos); } // printf("Scenario #%d:/n%d/n/n",Case,ans); printf("%lld/n",ans); } return 0; }
题目:
Time Limit: 7000MS | Memory Limit: 65536K | |
Total Submissions: 20199 | Accepted: 7146 |
Description
Input
Output
Sample Input
5 9 1 0 5 4 3 1 2 3 0 Sample Output 6 0 Source