2019.01.20【NOIP提高组】模拟 B 组总结

22 篇文章 0 订阅
19 篇文章 0 订阅

似乎很久没有写过总结了。。。今天突然(被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=1nbji=1nai=ansi=1nj=1nbjai=ansi=1nai=ansj=1nbji=1n(aiansbi)=0
因此我们可以二分答案,判断 ∑ i = 1 n ( a i − a n s ∗ b i ) \sum_{i=1}^{n}(a_i-ans*b_i) i=1n(aiansbi)的值是否大于等于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[(x1ave)2+(x2ave)2++(x(n1)ave)2+(xnave)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[(x1ave)2+(x2ave)2++(x(n1)ave)2+(xnave)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) aP11(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) aP2a1(modP)
也就是说,在模P的意义下, a − 1 a^{-1} a1等价于 a P − 2 a^{P-2} aP2这一个整数。因此我们可以用快速幂求出它,就可以避免出错了。
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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值