rt.
这个题大概来说就是要支持区间乘一个浮点数、然后最后查每个位置的值。
我最开始的写法是直接差分,在 l 位置乘上 v,在 r+1 位置除上 v,然后做个前缀积。
同时开个数组特判一下这个位置是否有被 0 覆盖过。
但是这个样子会喜提 Wrong Answer on test 12。
code:
#include<bits/stdc++.h>
//#define int long long
#define ll long long
#define ull unsigned long long
#define ld long double
#define PII pair<int,int>
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define chkmax(a,b) a=max(a,b)
#define chkmin(a,b) a=min(a,b)
#define rep(k,l,r) for(int k=l;k<=r;++k)
#define per(k,r,l) for(int k=r;k>=l;--k)
#define cl(f,x) memset(f,x,sizeof(f))
using namespace std;
const int N=1e6+5;
const ld eps=1e-9;
ld d[N],l[N],r[N];
int t[N],a[N],b[N],s[N],c[N],h[N],len;
int get_id(int x) {
return lower_bound(t+1,t+len+1,x)-t;
}
void upd(int l,int r,ld val) {
if(fabs(val)>eps) {
d[l]*=val;
d[r+1]/=val;
} else {
++s[l];
--s[r+1];
}
}
void solve() {
int n,m;
scanf("%d%d",&n,&m);
rep(i,1,n) {
scanf("%d%d%Lf%Lf",&a[i],&h[i],&l[i],&r[i]);
l[i]/=100.0; r[i]/=100.0;
t[++len]=a[i];
t[++len]=a[i]-h[i];
t[++len]=a[i]+h[i];
}
rep(i,1,m) {
scanf("%d%d",&b[i],&c[i]);
t[++len]=b[i];
}
sort(t+1,t+len+1);
len=unique(t+1,t+len+1)-t-1;
rep(i,0,len+1)
d[i]=1.0;
rep(i,1,n) {
int _l=get_id(a[i]-h[i]),p=get_id(a[i]),_r=get_id(a[i]+h[i]);
upd(_l,p-1,1.0-l[i]);
upd(p+1,_r,1.0-r[i]);
}
rep(i,1,len) {
d[i]*=d[i-1];
s[i]+=s[i-1];
}
ld res=0;
rep(i,1,m) {
int x=get_id(b[i]);
if(!s[x])
res+=d[x]*c[i];
}
printf("%.9Lf\n",res);
}
signed main() {
int testcase=1;
//scanf("%d",&testcase);
while(testcase--)
solve();
return 0;
}
然后我又改成了在 l 处加 lnv,在 r+1 处减 lnv,然后前缀和处理,再取 exp 就过了/yiw
code:
#include<bits/stdc++.h>
//#define int long long
#define ll long long
#define ull unsigned long long
#define ld long double
#define PII pair<int,int>
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define chkmax(a,b) a=max(a,b)
#define chkmin(a,b) a=min(a,b)
#define rep(k,l,r) for(int k=l;k<=r;++k)
#define per(k,r,l) for(int k=r;k>=l;--k)
#define cl(f,x) memset(f,x,sizeof(f))
using namespace std;
const int N=1e6+5;
const ld eps=1e-9;
ld d[N],l[N],r[N];
int t[N],a[N],b[N],s[N],c[N],h[N],len;
int get_id(int x) {
return lower_bound(t+1,t+len+1,x)-t;
}
void upd(int l,int r,ld val) {
if(fabs(val)>eps) {
d[l]+=log(val);
d[r+1]-=log(val);
} else {
++s[l];
--s[r+1];
}
}
void solve() {
int n,m;
scanf("%d%d",&n,&m);
rep(i,1,n) {
scanf("%d%d%Lf%Lf",&a[i],&h[i],&l[i],&r[i]);
l[i]/=100.0; r[i]/=100.0;
t[++len]=a[i];
t[++len]=a[i]-h[i];
t[++len]=a[i]+h[i];
}
rep(i,1,m) {
scanf("%d%d",&b[i],&c[i]);
t[++len]=b[i];
}
sort(t+1,t+len+1);
len=unique(t+1,t+len+1)-t-1;
rep(i,0,len+1)
d[i]=log(1.0);
rep(i,1,n) {
int _l=get_id(a[i]-h[i]),p=get_id(a[i]),_r=get_id(a[i]+h[i]);
upd(_l,p-1,1.0-l[i]);
upd(p+1,_r,1.0-r[i]);
}
rep(i,1,len) {
d[i]+=d[i-1];
s[i]+=s[i-1];
}
ld res=0;
rep(i,1,m) {
int x=get_id(b[i]);
if(!s[x])
res+=exp(d[x])*c[i];
}
printf("%.9Lf\n",res);
}
signed main() {
int testcase=1;
//scanf("%d",&testcase);
while(testcase--)
solve();
return 0;
}
萌新求助这两种方法为什么会有这么大的精度差距/kel