加载中…

返回上一页

8月20日2022年多校冲刺NOIP联训测试13

题面和下发文件

A.隔离

简单的二分,算是签到题了.

二分要求的dis,每次check,选点时贪心选择离上一个点相隔dis的点,如果那个点不能使用,则找到下一个区间的起点,如果最终能放得下n个人证明可行,否则不可行.

点击查看代码
#include<bits/stdc++.h>
#pragma GCC optomize(2)
#define ll long long
#define rg register
#define rll rg ll
#define maxn 100001
using namespace std;
static inline ll read()
{
	rll f=0,x=0;rg char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return f?-x:x;
}
static inline void write(rll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);putchar(x%10|48);
}
struct node
{
	ll st,ed;
	inline friend bool operator<(rg node a,rg node b)
	{
		return a.st<b.st;
	}
}a[maxn];
ll n,m,k;
ll l,r,ans;
ll pos,now,num;
static inline bool chk(rll x)
{
	pos=1;now=1;num=a[1].st;
	while(now<=m)
	{
		if(x+num<=a[now].ed) pos++,num+=x;
		else
		{
			now++;
			if(num+x>=a[now].st&&num+x<=a[now].ed) pos++,num+=x;
			else if(num+x<a[now].st) pos++,num=a[now].st;
		}
	}
	return (pos>=n);
}
int main()
{
	n=read();m=read();
	for(rll i=1;i<=m;i++)
		a[i].st=read(),a[i].ed=read();
	sort(a+1,a+m+1);
	k=a[m].ed/(n-1);
	l=0;r=k+1;
	while(l<r)
	{
		rll mid=(l+r)>>1;
		if(chk(mid)) ans=mid,l=mid+1;
		else r=mid;
	}
	write(ans);
	return 0;
}

B.绽放的花火

一个奇妙的dp题.

设dp[i]表示从上一格走到i格(不含后退的)需要步数的期望值,那么有转移 成立.

统计答案时只需要将每一步的dp加和即可,即 ,其中 为总共所需步数(就是每一维的减一,因为开始就是在1的位置).

点击查看代码
#include<bits/stdc++.h>
#pragma GCC optomize(2)
#define ll long long
#define rg register
#define rll rg ll
#define mod 1000000007
using namespace std;
static inline ll read()
{
	rll f=0,x=0;rg char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return f?-x:x;
}
static inline void write(rll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);putchar(x%10|48);
}
ll t,k;
ll p,ny,s;
ll dp,ans;
static inline ll ksm(rll a,rll b)
{
	rll ans=1;a%=mod;for(rll i=b;i;i>>=1) { if(i&1)ans=ans*a%mod; a=a*a%mod; }return ans;
}
int main()
{
	t=read();
	while(t--)
	{
		dp=ans=1;s=0;k=read();
		for(rll i=1;i<=k;i++) s+=read()-1;
		p=read();ny=ksm(p,mod-2);
		// dp[i]只与dp[i-1]有关,所以自然可以压掉一个数组
		for(rll i=2;i<=s;i++) dp=ny*((1-p+mod)*dp%mod+1)%mod,ans=(ans+dp)%mod;
		write(ans);puts("");
	}
	return 0;
}

C.美化数列

显然是一道线段树的题,由于要加入的数为一个等差/等比/斐波那契数列,因此不能只是用一个普通的线段树了,要把它稍微改一下.

由于等比数列的比值和斐波那契数列是已知的,所以可以先预处理出这些数列的内容,然后下传3个tag,分别是等差、等比和斐波那契数列的标记.在每次pushdown时,把线段树上点的值修改一下,再记录一下差值,在下一个节点pushdown时加一下.最后查询和普通线段树是一样的.

点击查看代码
#include<bits/stdc++.h>
#pragma GCC optomize(2)
#define ll long long
#define rg register
#define rll rg ll
#define maxn 400001
#define mod 19260817
using namespace std;
static inline ll read()
{
	rll f=0,x=0;rg char ch=getchar();
	while(ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return f?-x:x;
}
static inline void write(rll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);putchar(x%10|48);
}
struct node
{
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
	ll v,tag1,tag2,tag3;
}t[maxn];
ll n,m,d;
ll a[maxn>>1];
ll op,l,r,k,b;
ll f1[maxn],sum1[maxn],f2[maxn],sum2[maxn],g[maxn],sum[maxn];
ll k1[maxn],b1[maxn],k2[maxn],g1[maxn],g2[maxn];
static inline void shai()
{
	f1[1]=f2[2]=sum1[1]=sum1[2]=sum2[2]=g[1]=sum[1]=1;f1[2]=f2[1]=sum2[1]=0;
	for(rll i=3;i<=n;i++) f1[i]=(f1[i-1]+f1[i-2])%mod,sum1[i]=(sum1[i-1]+f1[i])%mod,f2[i]=(f2[i-1]+f2[i-2])%mod,sum2[i]=(sum2[i-1]+f2[i])%mod;
	for(rll i=2;i<=n;i++) g[i]=g[i-1]*d%mod,sum[i]=(sum[i-1]+g[i])%mod;
}
static inline void add1(rll rt,rll l,rll r,rll x,rll y,rll k,rll b)
{
	k=(k+(l-x)*b)%mod;t[rt].v=(t[rt].v+((((k<<1)+b*(r-l))*(r-l+1))>>1)%mod)%mod;
	k1[rt]+=k;b1[rt]+=b;t[rt].tag1=1;
}
static inline void add2(rll rt,rll l,rll r,rll x,rll y,rll k)
{
	k=k*g[l-x+1]%mod;t[rt].v=(t[rt].v+sum[r-l+1]*k%mod)%mod;
	k2[rt]+=k;t[rt].tag2=1;
}
static inline void add3(rll rt,rll l,rll r,rll x,rll y,rll p1,rll p2)
{
	if(l==r) { t[rt].v=(t[rt].v+f1[l-x+1]*p1%mod+f2[l-x+1]*p2%mod)%mod; return; }
	rll ta=f1[l-x+1]*p1%mod+f2[l-x+1]*p2%mod,tb=f1[l-x+2]*p1%mod+f2[l-x+2]*p2%mod;
	t[rt].v=(t[rt].v+ta*sum1[r-l+1]%mod+tb*sum2[r-l+1]%mod)%mod;
	g1[rt]=(g1[rt]+ta)%mod;g2[rt]=(g2[rt]+tb)%mod;t[rt].tag3=1;
}
#define pushup(x) t[x].v=(t[ls(x)].v+t[rs(x)].v)%mod
static inline void pushdown(rll rt,rll l,rll r)
{
	rll mid=(l+r)>>1;
	if(t[rt].tag1)
	{
		add1(ls(rt),l,mid,l,r,k1[rt],b1[rt]);
		add1(rs(rt),mid+1,r,l,r,k1[rt],b1[rt]);
		k1[rt]=b1[rt]=t[rt].tag1=0;
	}
	if(t[rt].tag2)
	{
		add2(ls(rt),l,mid,l,r,k2[rt]);
		add2(rs(rt),mid+1,r,l,r,k2[rt]);
		k2[rt]=t[rt].tag2=0;
	}
	if(t[rt].tag3)
	{
		add3(ls(rt),l,mid,l,r,g1[rt],g2[rt]);
		add3(rs(rt),mid+1,r,l,r,g1[rt],g2[rt]);
		g1[rt]=g2[rt]=t[rt].tag3=0;
	}
}
static inline void build(rll rt,rll l,rll r)
{
	if(l==r) { t[rt].v=a[l]; return; }
	rll mid=(l+r)>>1;build(ls(rt),l,mid);build(rs(rt),mid+1,r);
	pushup(rt);
}
static inline void upd1(rll rt,rll l,rll r,rll x,rll y,rll k,rll d)
{
	if(x<=l&&r<=y) { add1(rt,l,r,x,y,k,d); return; }
	pushdown(rt,l,r);rll mid=(l+r)>>1;
	if(x<=mid) upd1(ls(rt),l,mid,x,y,k,d);
	if(y>mid) upd1(rs(rt),mid+1,r,x,y,k,d);
	pushup(rt);
}
static inline void upd2(rll rt,rll l,rll r,rll x,rll y,rll k)
{
	if(x<=l&&r<=y) { add2(rt,l,r,x,y,k); return; }
	pushdown(rt,l,r);rll mid=(l+r)>>1;
	if(x<=mid) upd2(ls(rt),l,mid,x,y,k);
	if(y>mid) upd2(rs(rt),mid+1,r,x,y,k);
	pushup(rt);
}
static inline void upd3(rll rt,rll l,rll r,rll x,rll y)
{
	if(x<=l&&r<=y) { add3(rt,l,r,x,y,1,1); return; }
	pushdown(rt,l,r);rll mid=(l+r)>>1;
	if(x<=mid) upd3(ls(rt),l,mid,x,y);
	if(y>mid) upd3(rs(rt),mid+1,r,x,y);
	pushup(rt);
}
static inline ll query(rll rt,rll l,rll r,rll x,rll y)
{
	if(x<=l&&r<=y) return t[rt].v;
	pushdown(rt,l,r);rll mid=(l+r)>>1;
	if(y<=mid) return query(ls(rt),l,mid,x,y);
	if(x>mid) return query(rs(rt),mid+1,r,x,y);
	return (query(ls(rt),l,mid,x,y)+query(rs(rt),mid+1,r,x,y))%mod;
}
int main()
{
	n=read();m=read();d=read();shai();
	for(rll i=1;i<=n;i++) a[i]=read()%mod;
	build(1,1,n);
	while(m--)
	{
		op=read();
		switch(op)
		{
		case 1:
			l=read();r=read();k=read();b=read();
			upd1(1,1,n,l,r,k,b);
			break;
		case 2:
			l=read();r=read();k=read();
			upd2(1,1,n,l,r,k);
			break;
		case 3:
			l=read();r=read();
			upd3(1,1,n,l,r);
			break;
		case 4:
			l=read();r=read();
			write((query(1,1,n,l,r)%mod+mod)%mod);puts("");
			break;
		}
	}
	return 0;
}

未完不续...

(D题不会)

posted @ 2022-08-20 14:00  1Liu  阅读(64)  评论(0)    收藏  举报