期末大水题-模拟考

虽说之前还考了几场,当时忘记写就咕咕咕可还行

话说不用考期末考真不错!!

进入正题!

这次的题真的水(然而才130QAQ),T1精度打死卡不过去绝对是标程炸了(hdu能过),T2贪心乱做,数据甚至开到1e7没问题,T3做法想出来了然而没想到要逆着做矩阵(mod要有逆元的操作),于是乎 30 + 100 + 0 (悲)。

只能说思考还是不够深入,and做完前两道还剩2个小时不该摆烂的。。。。頑張りましょう!

T1 strange

image

(才不会告诉你是因为懒得打题面才放图)

画图发现 0 ~ 100 范围内的函数是下凸的,直接二分找导数为零的点。对于 a×xy,导数为 a×y×xy1,函数相加导数直接相加。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n;
double k,l[8];
inline double f(double x){
	l[1]=x;
	for(int i=2;i<=7;i++)l[i]=l[i-1]*x;
	return 6*l[7]+8*l[6]+7*l[3]+5*l[2]-k*x;
}
inline double dao(double x){
	l[1]=x;
	for(int i=2;i<=6;i++)l[i]=l[i-1]*x;
	return 42*l[6]+48*l[5]+21*l[2]+10*l[1]-k;
}
inline void work(){
	double l=0,r=100,mid;
	while(r-l>=0.0000001){
		mid=(l+r)/2;
		if(dao(mid)>=0.0000001)r=mid;
		else l=mid;
	}
	double ans=f(l);
	if(ans>0)ans-=0.0001;
	printf("%.4lf\n",ans);
	return ;
}
signed main(){
//	freopen("strange.in","r",stdin);
//	freopen("strange.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%lf",&k);
		work();
	}
	return 0;
}

T2 pizza

image

真就随便怎么做都行,懒得放做法了...

点击查看代码
#include<bits/stdc++.h>
using namespace std;
inline int rd(){
	int f=1,j=0;
	char w=getchar();
	while(w>'9'||w<'0')w=getchar();
	while(w>='0'&&w<='9'){
		j=(j<<3)+(j<<1)+w-'0';
		w=getchar();
	}
	return f*j;
}
const int N=100001;
struct node{
	int x,t;
	bool operator <(const node &a)const{return t>a.t;}
};
priority_queue<node>l,r;
int L,R,n,m;
long long ans;
signed main(){
//	freopen("pizza.in","r",stdin);
//	freopen("pizza.out","w",stdout);
	n=rd();m=rd();
	for(int i=1;i<=n;i++){
		int x=rd(),y=rd(),z=rd(),t=abs(y-z);
		if(y>z)L+=x,ans+=1ll*y*x,l.push((node){x,t});
		else R+=x,ans+=1ll*z*x,r.push((node){x,t}); 
	}
	if(L%m+R%m>m){
		printf("%lld",ans);
		return 0;
	}
	long long ll=0,rr=0;
	int ml=L%m,mr=R%m;
	while(ml>0){
		if(l.top().x<=ml){
			ll+=1ll*l.top().x*l.top().t;
			ml-=l.top().x;
		}
		else{
			ll+=1ll*ml*l.top().t;
			ml=0;
		}
		l.pop();
	}
	while(mr>0){
		if(r.top().x<=mr){
			rr+=1ll*r.top().x*r.top().t;
			mr-=r.top().x;
		}
		else{
			rr+=1ll*mr*r.top().t;
			mr=0;
		}
		r.pop();
	}
	ans-=min(ll,rr);
	printf("%lld",ans);
	return 0;
}
/*
6 10
7 4 7
5 8 8
12 5 8
6 11 6
3 3 7
5 9 6

3 12
3 5 7
4 6 7
5 9 5
*/

T3 recover

image

第一眼看到这种相关两个量的递推式就想到矩阵,因为有模数所以要先求逆矩阵(逆元)倒着乘回去,有两种做法:

  • 线段树维护区间修改

  • 线段树维护当前点所乘的逆矩阵,把区间改为差分,加入/减去一个矩阵即把当前点(以修改时间为下标)到根的值全部更新一遍(稳定 nlogn!)

点击查看代码
#include<bits/stdc++.h>
using namespace std;
inline int rd(){
	int f=1,j=0;
	char w=getchar();
	while(w>'9'||w<'0')w=getchar();
	while(w>='0'&&w<='9'){
		j=(j<<3)+(j<<1)+w-'0';
		w=getchar();
	}
	return f*j;
}
const int N=100001,mod=1000000007;
struct mat{
	int f[2][2];
	mat operator *(const mat &a)const{
		mat b;
		for(int x=0;x<=1;x++){
			for(int y=0;y<=1;y++){
				b.f[x][y]=0;
				for(int j=0;j<=1;j++)b.f[x][y]=(1ll*f[x][j]*a.f[j][y]%mod+b.f[x][y]+mod)%mod;
			}
		}
		return b;
	}
}ele,X[N],Y[N],tree[N*4],aim;
int n,m,A[N],B[N],an[2][N];
struct node{
	int l,pla,x,y,t;
}q[N*2];
bool cmp(node a,node b){return a.pla<b.pla;}
void update(int u){
	tree[u]=tree[u*2]*tree[u*2+1];
	return ;
}
void add(int u,int l,int r,int pla){
	if(l==r){
		tree[u]=aim;
		return ;
	}
	int mid=(l+r)/2;
	if(pla<=mid)add(u*2,l,mid,pla);
	else add(u*2+1,mid+1,r,pla);
	update(u);
	return ;
}
int extend_gcd(int a,int b,int &x,int &y){
	if(b==0){
		x=1;y=0;
		return 0;
	}
	extend_gcd(b,a%b,x,y);
	int tmp=x;
	x=y;
	y=tmp-(a/b)*y;
	return 0;
}
int innode(int a){
	int x,y;
	extend_gcd(a,mod,x,y);
	return (mod+x%mod)%mod;
}
signed main(){
//	freopen("recover.in","r",stdin);
//	freopen("recover.out","w",stdout);
	ele.f[0][0]=ele.f[1][1]=1,ele.f[0][1]=ele.f[1][0]=0;
	X[1].f[0][0]=innode(3),X[1].f[0][1]=0,X[1].f[1][0]=-innode(6),X[1].f[1][1]=innode(2);
	Y[1].f[0][0]=1ll*3*innode(5)%mod,Y[1].f[0][1]=-innode(5),Y[1].f[1][0]=-innode(5),Y[1].f[1][1]=1ll*2*innode(5);
	for(int i=2;i<N;i++)X[i]=X[i-1]*X[1],Y[i]=Y[i-1]*Y[1];
	n=rd();m=rd();
	for(int i=1;i<=m*4;i++)tree[i]=ele;
	for(int i=1;i<=n;i++)A[i]=rd();
	for(int i=1;i<=n;i++)B[i]=rd();
	for(int i=1;i<=m;i++){
		int a=rd(),l=rd(),r=rd(),k=rd();
		q[i*2-1]=(node){0,l,a,k,m-i+1};
		q[i*2]=(node){1,r+1,a,k,m-i+1};
	}
	sort(q+1,q+m*2+1,cmp);
	int nown=1;
	for(int i=1;i<=n;i++){
		while(q[nown].pla<=i&&nown<=m*2){
			if(q[nown].l==0){
				if(q[nown].x==1)aim=X[q[nown].y];
				else aim=Y[q[nown].y];
				add(1,1,m,q[nown].t);
			}
			else{
				aim=ele;
				add(1,1,m,q[nown].t);
			}
			nown++;
		}
		mat ans=tree[1];
		an[0][i]=((1ll*A[i]*ans.f[0][0]%mod+1ll*B[i]*ans.f[1][0])%mod+mod)%mod;
		an[1][i]=((1ll*A[i]*ans.f[0][1]%mod+1ll*B[i]*ans.f[1][1])%mod+mod)%mod;
	}
	for(int i=0;i<=1;i++){
		for(int j=1;j<=n;j++)printf("%d ",an[i][j]);
		printf("\n");
	}
	return 0;
}
posted @   flywatre  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示