题目大意:给出 n n n个数的分类和预测值,(还有一些概念: T P R TPR TPR, F P R FPR FPR, A U C AUC AUC)求 A U C AUC AUC。
分析:
不难发现最后要求的是若干个矩形的面积,分段求就可以。先给n个数排序然后根据取每个 a i a_i ai为 θ θ θ,若 a i − 1 a_{i-1} ai−1为 + + +则 F N FN FN++,若为 − - −则 T N TN TN++。
ac代码:
#include <bits/stdc++.h>
using namespace std;
typedef long double ld;
const int N = 1e6+6;
map<char,vector<int> >mp[4];
struct node{
char c;ld x;int cnt;int l,r;
bool operator<(const node&t)const{
if(x == t.x)return c < t.c;//+,-
return x < t.x;
}
}p[N],q[N];
int n;
ld calf(ld fp,ld tn){
// printf("aaaaaa%.10f\n",1.0*fp/(1.0*tn+1.0*fp));
return (ld)fp/((ld)tn+(ld)fp);
}
ld calt(ld tp,ld fn){
return (ld)tp/((ld)tp+(ld)fn);
}
int main(){
ios::sync_with_stdio(false);
cin >> n;
for(int i = 0;i < n;i++){
char c;ld x;cin >> c >> x;
p[i].c = c,p[i].x = x;
}
sort(p,p+n);ld ans = 0.0;int idx = 0;
for(int i = 0;i < n;i++){
if(p[i].x == p[i-1].x)continue;
node tmp = {'+',p[i].x},tmp1 = {'-',p[i].x};
p[i].cnt = upper_bound(p,p+n,tmp1) - lower_bound(p,p+n,tmp);
q[idx] = p[i];q[idx].l = lower_bound(p,p+n,tmp) - p;
q[idx].r = upper_bound(p,p+n,tmp1) - p;idx++;
}
ld theta = q[0].x;int tp = 0,fp = 0,tn = 0,fn = 0;
for(int i = 0;i < n;i++){
if(p[i].c=='+')tp++;
else fp++;
}
// printf("%d %d %d %d\n",tp,fp,tn,fn);
ld f = calf((ld)fp,(ld)tn),t = calt((ld)tp,(ld)fn);
// cout << theta << endl;
// printf("%.10f %.10f\n",1.0*fp/(1.0*fp+1.0*tn),(ld)tp/((ld)tp+(ld)fn));
// cout << fixed << setprecision(10) << f <<" "<<t << endl;
for(int i = 1;i < idx;i++){
ld theta = q[i].x;int l = q[i-1].l,r = q[i-1].r;
for(int j = l;j < r;j++)
if(p[j].c=='+')fn++,tp--;
else tn++,fp--;
// if(fp <= 0||tp <= 0)break;
// cout << theta << endl;
// cout << fixed << setprecision(10)<<tp<<" "<<fp<<" "<<tn<<" "<<fn<<endl;
ld f1 = calf((ld)fp,(ld)tn),t1 = calt((ld)tp,(ld)fn);
// cout << fixed << setprecision(10)<<f1<<" "<<t1<<endl;
ans = ans+(f-f1)*t1;f = f1;t = t1;
}
// ans = ans+t*f;
cout << fixed << setprecision(12)<<ans << endl;
// for(int i = 0;i < idx;i++)cout << q[i].c << " " << q[i].x << " "<<q[i].cnt << endl;
return 0;
}
/*
8
+ 34
+ 33
+ 26
- 34
- 38
+ 39
- 7
- 27
3
+ 2
- 3
- 1
6
+ 7
- 2
- 5
+ 4
- 2
+ 6
*/
p.s. 调了好几个小时人快麻了,问题主要出在 T P TP TP, T N TN TN, F P FP FP, F N FN FN的理解上。记得记录 a i − 1 a_{i-1} ai−1的个数。时间复杂度 O n O_n On。