似乎很久没有写过总结了。。。今天突然(被XC安排)写总结。
总结
怎么今天的题目都是王仙女的?还神啊神啊的,鬼畜得很啊!
不管这么多,水分要紧!
我先看了看第一题,公式都给出来了,怎么这么水?不过出题人绝对没那么善良,细心的我发现了一行大字:
对于100%的数据,M≤ 1 0 5 10^5 105,a_1,q≤ 1 0 9 10^9 109,n≤ 1 0 18 10^{18} 1018
原来是高精度!我于是转到第二题——
这题十分眼熟,和前几天某一道叫做*“最佳团队”*的A组题目一样是求比值。于是我立刻想到了二分答案+DP。呵呵,这么水的题,我分分钟AK!
自信满满的我再看第三题,什么?方差是什么鬼!一脸懵逼,尝试推了一下式子,仍然毫无头绪,遂转到第一题。
这时,我发现第一题要模
1
0
9
+
7
10^9+7
109+7,立刻想到逆元。于是快乐地敲起了键盘来。
再看第二题,和那道A组题一样,先推式子再说~
∑
i
=
1
n
a
i
∑
j
=
1
n
b
j
=
a
n
s
∑
i
=
1
n
a
i
∑
j
=
1
n
b
j
=
a
n
s
∑
i
=
1
n
a
i
=
a
n
s
∗
∑
j
=
1
n
b
j
∑
i
=
1
n
(
a
i
−
a
n
s
∗
b
i
)
=
0
\begin{aligned} \frac{\sum_{i=1}^{n}a_i}{\sum_{j=1}^{n}b_j}=ans\\ \sum_{i=1}^{n}\frac{a_i}{{\sum_{j=1}^{n}b_j}}=ans\\ \sum_{i=1}^{n}a_i=ans*{\sum_{j=1}^{n}b_j}\\ \sum_{i=1}^{n}(a_i-ans*b_i)=0 \end{aligned}
∑j=1nbj∑i=1nai=ansi=1∑n∑j=1nbjai=ansi=1∑nai=ans∗j=1∑nbji=1∑n(ai−ans∗bi)=0
因此我们可以二分答案,判断
∑
i
=
1
n
(
a
i
−
a
n
s
∗
b
i
)
\sum_{i=1}^{n}(a_i-ans*b_i)
∑i=1n(ai−ans∗bi)的值是否大于等于0,如果是,那么二分的值就是合法的。于是我就想到了一个方法——
设
f
i
,
j
f_{i,j}
fi,j表示到了第 i 个岛屿,选了 j 个的最大贡献值。
状态转移方程显然,可是我却细心地发现了一行大字:
对于100%的数据,2≤K≤N≤100000,1≤a,b≤1000
天哪!DP会世超!
这时我才发现这题水得连DP都不用。
不要问我为什么总是这个人在这里晃来晃去 原来这题直接贪心判定就好了!!!
啊,今天的题目实在是太水了!我于是万分自信地点开了第三题。
第一眼扫过去,在线的区间维护+询问——线段树!
然而我实在是被方差搞懵了,甚至还纠结了半天是
1
n
[
(
x
1
−
a
v
e
)
2
+
(
x
2
−
a
v
e
)
2
+
⋯
+
(
x
(
n
−
1
)
−
a
v
e
)
2
+
(
x
n
−
a
v
e
)
2
]
\frac{1}{n[(x_1-ave)^2+(x_2-ave)^2+⋯+(x_(n-1)-ave)^2+(x_n-ave)^2]}
n[(x1−ave)2+(x2−ave)2+⋯+(x(n−1)−ave)2+(xn−ave)2]1还是
1
n
⋅
[
(
x
1
−
a
v
e
)
2
+
(
x
2
−
a
v
e
)
2
+
⋯
+
(
x
(
n
−
1
)
−
a
v
e
)
2
+
(
x
n
−
a
v
e
)
2
]
\frac{1}{n}\cdot[(x_1-ave)^2+(x_2-ave)^2+⋯+(x_(n-1)-ave)^2+(x_n-ave)^2]
n1⋅[(x1−ave)2+(x2−ave)2+⋯+(x(n−1)−ave)2+(xn−ave)2]。最后推了一下样例才发现是后者。
那么长的一坨式子,肯定要推一推啦!我于是陷入了无尽的推式子深渊中,还搞错了几次,心态崩了,只好打前2题,拿到200分再说。
30 minutes later…
咦,可以交代码了,我于是交了T1,发现运行了很长时间十分不对劲,于是稍加修改再交一遍。这时右边的LDD上不了网,于是好心帮他插网线,然后他还是上不了网。于是我手残刷新了一下T3——就再也加载不出来了!!!
颓唐中,x minutes later,网络终于来了。
这时,我的式子终于推出来了!!!然而只剩下30分钟了。
我狂敲键盘,刚敲完,长吁一口气,点开OJ时,发现自己晚了1秒钟,比赛结束了!
总结:比赛时要把握好时间,不要因不必要的因素影响做题。
后记
先大致讲一下各道题目的解法。
T1:有个模的意义下除法不好处理,就要用逆元,求逆元可以用费马小定理。
a
P
−
1
≡
1
(
m
o
d
P
)
a^{P-1}\equiv 1\quad(mod P)
aP−1≡1(modP)
其中
gcd
(
a
,
P
)
=
1
\gcd(a,P)=1
gcd(a,P)=1且P为质数。
我们移一下项
a
P
−
2
≡
1
a
(
m
o
d
P
)
a^{P-2}\equiv \frac{1}{a}\quad(mod P)
aP−2≡a1(modP)
也就是说,在模P的意义下,
a
−
1
a^{-1}
a−1等价于
a
P
−
2
a^{P-2}
aP−2这一个整数。因此我们可以用快速幂求出它,就可以避免出错了。
T2:这题XC让我来讲。
于是我先讲啊讲,讲到二分部分,不小心说出了一个高大上的名词:
我们就可以记录每一个点的贡献c,c[i]=a[i]/b[i]
接着同学们就懵逼了——贡献是嘛东西哩?
最后我刚走下台,就有几个同学说他们听不懂,害得我尴尬地走回上台重讲。
T3:线段树乱搞一下就好了(不要问我为什么改了2天才AC)
开源盛世
T1
#include<cstdio>
using namespace std;
#define ll unsigned long long
#define mod 1000000007
inline ll pow(ll x,ll y)
{
ll s=1;
while(y)
{
if(y&1) s=s*x%mod;
x=x*x%mod,y>>=1;
}
return s;
}
int main()
{
ll n,m,a,q;
scanf("%llu",&m);
while(m--)
{
scanf("%llu%llu%llu",&a,&q,&n);
if(q==1) printf("%llu\n",n%mod*a%mod);
else
{
a=(pow(q,n)+mod-1)%mod*a%mod;
printf("%llu\n",a*pow(q-1,mod-2)%mod);
}
}
return 0;
}
T2
#include<cstdio>
#include<algorithm>
using namespace std;
#define e 1e-4
#define N 100005
#define inf 100000000
struct island
{
double a,b,c;
}a[N];
double l,r,mid,s;
inline bool cmp(island x,island y){return x.c>y.c;}
int main()
{
freopen("thunder.in","r",stdin);
freopen("thunder.out","w",stdout);
int n,m,i,j;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++) scanf("%lf",&a[i].a);
for(i=1;i<=n;i++) scanf("%lf",&a[i].b);
l=0,r=inf;
while(r-l>=e)
{
mid=(l+r)/2;
for(i=1;i<=n;i++) a[i].c=a[i].a-a[i].b*mid;
sort(a+1,a+n+1,cmp);
for(i=1,s=0;i<=m;i++) s+=a[i].c;
if(s>=0) l=mid;
else r=mid;
}
printf("%.3lf\n",l);
return 0;
}
T3
#include<cstdio>
#include<cstring>
using namespace std;
#define ll long long
#define LF long double
#define N 100005
#define lson k<<1
#define rson k<<1|1
#define update(x) a[k].x=a[lson].x+a[rson].x
struct node
{
int sum,lazy,cnt;ll sq;
node(){sum=lazy=cnt=0,sq=0;}
}a[N*17];
int val[N];ll temp;
inline void pushdown(int k)
{
int num=a[k].lazy;a[k].lazy=0;
temp=a[lson].sum,temp*=num<<1,a[lson].sq+=temp;
temp=a[lson].cnt*num,a[lson].sum+=temp;
temp*=num,a[lson].sq+=temp;
temp=a[rson].sum,temp*=num<<1,a[rson].sq+=temp;
temp=a[rson].cnt*num,a[rson].sum+=temp;
temp*=num,a[rson].sq+=temp;
a[rson].lazy+=num,a[lson].lazy+=num;
}
void build(int k,int l,int r)
{
if(l==r)
{
a[k].sum=val[l];
a[k].sq=val[l]*val[l];
a[k].cnt=1;
}
else
{
int mid=l+r>>1;
build(lson,l,mid);
build(rson,mid+1,r);
update(sum),update(cnt),update(sq);
}
}
void add(int k,int l,int r,int x,int y,int num)
{
if(a[k].lazy)
if(l<r) pushdown(k);
if(l==x&&r==y)
{
temp=a[k].sum,temp*=num<<1,a[k].sq+=temp;
temp=a[k].cnt*num,a[k].sum+=temp;
temp*=num,a[k].sq+=temp;
a[k].lazy=num;
}
else
{
int mid=l+r>>1;
if(y<=mid) add(lson,l,mid,x,y,num);
else if(x>mid) add(rson,mid+1,r,x,y,num);
else add(lson,l,mid,x,mid,num),add(rson,mid+1,r,mid+1,y,num);
update(sum),update(sq);
}
}
int query_sum(int k,int l,int r,int x,int y)
{
if(a[k].lazy)
if(l<r) pushdown(k);
if(l==x&&r==y) return a[k].sum;
int mid=l+r>>1;
if(y<=mid) return query_sum(lson,l,mid,x,y);
if(x>mid) return query_sum(rson,mid+1,r,x,y);
return query_sum(lson,l,mid,x,mid)+query_sum(rson,mid+1,r,mid+1,y);
}
ll query_sq(int k,int l,int r,int x,int y)
{
if(l==x&&r==y) return a[k].sq;
int mid=l+r>>1;
if(y<=mid) return query_sq(lson,l,mid,x,y);
if(x>mid) return query_sq(rson,mid+1,r,x,y);
return query_sq(lson,l,mid,x,mid)+query_sq(rson,mid+1,r,mid+1,y);
}
int main()
{
int n,m,i,k,x,y,z;LF ave,sum,sq,len;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++) scanf("%d",&val[i]);
build(1,1,n);
while(m--)
{
scanf("%d%d%d",&k,&x,&y);
switch(k)
{
case 0:
add(1,1,n,x,x,y);break;
case 1:
scanf("%d",&z);
add(1,1,n,x,y,z);break;
case 2:
printf("%d\n",query_sum(1,1,n,x,y));break;
default:
len=y-x+1,sum=query_sum(1,1,n,x,y);
sq=query_sq(1,1,n,x,y),ave=sum/len;
printf("%.10LF\n",sq/len-ave*ave);break;
}
}
return 0;
}