6.19 考试修改+总结

QAQ 又是一套水题集合

然后忧伤的故事是老师把时间调到了四个小时半

我又因为想要出道题花了半个小时写了一些其他的东西

然后最后没有写完题!QAQ

不然第三题可能多拿点分

上午的时候把所有题目的正解都想了出来

唯一美中不足的是自己想的第三题是O(n^4*300)的是时间复杂度

实际上离散化区间之后只会有n个区间,时间复杂度就是O(n^5)了QAQ

先说题解把

第一题 决战圆锥曲线

显然给定你的那个函数a*x+b*y+c*x*y对于x,y是相对等价的

又因为题目的输入具有随机性,显然可以通过维护线段树在线段树上做kd_tree的查询来完成

注意到x,y都是正整数,而且x的范围就区间的范围,所以我们利用线段树维护y的最大值就可以完成类似kd_tree的查询了

时间复杂度略微有些玄学,听说随机数据下O(nlog^2n)?

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std;

typedef long long LL;
const int maxn=100010;
const LL oo=1LL<<60;
int n,m,x,p,v,le,re;
int A,B,C;
int a[maxn];
int mx[maxn<<2];
int mn[maxn<<2];
bool vis[maxn<<2];
LL ans;

int Get_R(){
	x=(1LL*100000005*x+20150609)%998244353;
	return x/100;
}
void read(int &num){
	num=0;char ch=getchar();
	while(ch<‘!‘)ch=getchar();
	while(ch>=‘0‘&&ch<=‘9‘)num=num*10+ch-‘0‘,ch=getchar();
}
void build(int o,int L,int R){
	if(L==R){
		mx[o]=mn[o]=a[L];
		return;
	}
	int mid=(L+R)>>1;
	build(o<<1,L,mid);
	build(o<<1|1,mid+1,R);
	mx[o]=max(mx[o<<1],mx[o<<1|1]);
	mn[o]=min(mn[o<<1],mn[o<<1|1]);
}
void down(int o,int l,int r){
	int Mn,Mx;
	vis[l]^=1;vis[r]^=1;
	Mn=mn[l];Mx=mx[l];
	mx[l]=100000-Mn;mn[l]=100000-Mx;
	Mn=mn[r];Mx=mx[r];
	mx[r]=100000-Mn;mn[r]=100000-Mx;
	vis[o]=false;
}
void UPD(int o,int L,int R){
	if(L==R){mx[o]=mn[o]=v;return;}
	int mid=(L+R)>>1;
	int l=(o<<1),r=(l|1);
	if(vis[o])down(o,l,r);
	if(p<=mid)UPD(l,L,mid);
	else UPD(r,mid+1,R);
	mx[o]=max(mx[l],mx[r]);
	mn[o]=min(mn[l],mn[r]);
}
void modify(int o,int L,int R){
	if(L>=le&&R<=re){
		vis[o]^=1;
		int Mn=mn[o],Mx=mx[o];
		mx[o]=100000-Mn;
		mn[o]=100000-Mx;
		return;
	}
	int mid=(L+R)>>1;
	int l=(o<<1),r=(l|1);
	if(vis[o])down(o,l,r);
	if(re<=mid)modify(l,L,mid);
	else if(le>mid)modify(r,mid+1,R);
	else modify(l,L,mid),modify(r,mid+1,R);
	mx[o]=max(mx[l],mx[r]);
	mn[o]=min(mn[l],mn[r]);
}
LL Get_ans(int o,int L,int R){
	int tmp=mx[o];LL k=(A+1LL*C*tmp);
	return k*R+1LL*B*tmp;
}
void kd_ask(int o,int L,int R){
	if(L==R){
		ans=max(ans,1LL*A*L+1LL*B*mn[o]+1LL*C*L*mn[o]);
		return;
	}
	int mid=(L+R)>>1;
	int l=(o<<1),r=(l|1);
	if(vis[o])down(o,l,r);
	LL d1=Get_ans(l,L,mid);
	LL d2=Get_ans(r,mid+1,R);
	if(d1>d2){
		if(d1>ans)kd_ask(l,L,mid);
		if(d2>ans)kd_ask(r,mid+1,R);
	}else{
		if(d2>ans)kd_ask(r,mid+1,R);
		if(d1>ans)kd_ask(l,L,mid);
	}return;
}
void ask(int o,int L,int R){
	if(L>=le&&R<=re){
		kd_ask(o,L,R);
		return;
	}
	int mid=(L+R)>>1;
	int l=(o<<1),r=(l|1);
	if(vis[o])down(o,l,r);
	if(re<=mid)ask(l,L,mid);
	else if(le>mid)ask(r,mid+1,R);
	else ask(l,L,mid),ask(r,mid+1,R);
}

int main(){
	freopen("conic.in","r",stdin);
	freopen("conic.out","w",stdout);
	read(n);read(m);read(x);
	for(int i=1;i<=n;++i)a[i]=Get_R()%100001;
	build(1,1,n);
	while(m--){
		char ch=getchar();
		while(ch<‘!‘)ch=getchar();
		if(ch==‘C‘){
			p=Get_R()%n+1;v=Get_R()%100001;
			UPD(1,1,n);
		}else if(ch==‘R‘){
			le=Get_R()%n+1;re=Get_R()%n+1;
			if(le>re)swap(le,re);
			modify(1,1,n);
		}else{
			read(A);read(B);read(C);
			ans=-oo;
			le=Get_R()%n+1;re=Get_R()%n+1;
			if(le>re)swap(le,re);
			ask(1,1,n);
			printf("%lld\n",ans);
		}
	}return 0;
}

第二题

显然有30分是白送给状态压缩或者插头DP的

之前有一道题目是最小割我用插头DP骗了90分,那么考虑这道题能不能用网络流解决

不难发现如果两个B可以消掉,这两个B的行的奇偶性一定不一样

这样对于B来说具有二分图的性质,但是还有考虑A的影响

而且我们的每个流都要表示一个B-A-B的方案

仔细思考后可以得到如下建图:

我们的S向行数是偶数的B连边,行数是奇数的B向T连边

对于行数是偶数的B我们向四个方向的A连边

对于每个A拆点限流

之后行数是偶数的A向左右两个方向的B连边

行数是奇数的A向上下两个方向的B连边

不难发现每个流都代表一个可行的L

那么求最大流即可,由于边权都是1,所以网络流跑的飞快

QAQ考试的时候心虚还写了个插头DP对拍QAQ

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<queue>
using namespace std;

const int maxn=500010;
const int oo=0x7fffffff;
int n,m,S,T,ans;
int c[510][510];
int idx[510][510],tot=0;
int h[maxn],cnt=1;
int vis[maxn];
struct edge{
	int to,next,w;
}G[8000010];
queue<int>Q;

void add(int x,int y,int z){
	++cnt;G[cnt].to=y;G[cnt].next=h[x];G[cnt].w=z;h[x]=cnt;
	++cnt;G[cnt].to=x;G[cnt].next=h[y];G[cnt].w=0;h[y]=cnt;
}
void read(int &num){
	num=0;char ch=getchar();
	while(ch<‘!‘)ch=getchar();
	while(ch>=‘0‘&&ch<=‘9‘)num=num*10+ch-‘0‘,ch=getchar();
}
bool BFS(){
	Q.push(S);
	for(int i=S;i<=T;++i)vis[i]=-1;
	vis[S]=0;
	while(!Q.empty()){
		int u=Q.front();Q.pop();
		for(int i=h[u];i;i=G[i].next){
			int v=G[i].to;
			if(vis[v]==-1&&G[i].w>0){
				vis[v]=vis[u]+1;
				Q.push(v);
			}
		}
	}return vis[T]!=-1;
}
int DFS(int x,int f){
	if(x==T||f==0)return f;
	int w,used=0;
	for(int i=h[x];i;i=G[i].next){
		if(vis[G[i].to]==vis[x]+1){
			w=f-used;
			w=DFS(G[i].to,min(w,G[i].w));
			G[i].w-=w;G[i^1].w+=w;
			used+=w;if(used==f)return used;
		}
	}
	if(!used)vis[x]=-1;
	return used;
}
void dinic(){
	ans=0;
	while(BFS())ans+=DFS(S,oo);
}

int main(){
	freopen("molecule.in","r",stdin);
	freopen("molecule.out","w",stdout);
	read(n);read(m);
	for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)read(c[i][j]);
	for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j){
			if(c[i][j]==0)continue;
			idx[i][j]=++tot;
			if(c[i][j]==1)++tot;
		}
	}S=0;T=tot+1;
	for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j){
			if(c[i][j]==0)continue;
			if(i&1){
				if(c[i][j]==2){
					add(S,idx[i][j],1);
					if(j-1>=1&&c[i][j-1]==1)add(idx[i][j],idx[i][j-1],1);
					if(j+1<=m&&c[i][j+1]==1)add(idx[i][j],idx[i][j+1],1);
					if(i-1>=1&&c[i-1][j]==1)add(idx[i][j],idx[i-1][j],1);
					if(i+1<=n&&c[i+1][j]==1)add(idx[i][j],idx[i+1][j],1);
				}else{
					add(idx[i][j],idx[i][j]+1,1);
					if(i-1>=1&&c[i-1][j]==2)add(idx[i][j]+1,idx[i-1][j],1);
					if(i+1<=n&&c[i+1][j]==2)add(idx[i][j]+1,idx[i+1][j],1);
				}
			}else{
				if(c[i][j]==2)add(idx[i][j],T,1);
				else{
					add(idx[i][j],idx[i][j]+1,1);
					if(j+1<=m&&c[i][j+1]==2)add(idx[i][j]+1,idx[i][j+1],1);
					if(j-1>=1&&c[i][j-1]==2)add(idx[i][j]+1,idx[i][j-1],1);
				}
			}
		}
	}dinic();
	printf("%d\n",ans);
	return 0;
}

第三题

我们注意到不能单独计算i比j强的概率并装包

因为概率之间会相互影响

所以我们不妨枚举每个点在那个区间里

不难发现其他点对于这个点只会有三种情况

win,lose,in(在区间里)

不妨设f(i,j)表示有i个点比当前点强且有j个点和当前点在一个区间里

转移的时候分情况装包就可以了

之后我们注意到对于一个状态f(i,j),当前点的排名可能是i+1->i+j+1

而且概率都是f(i,j)*P/(j+1) P是当前点在这个区间的概率

然后贡献给Ans(i)就可以了

时间复杂度O(n^5),考试的时候时间不够没有调出来(现在貌似被OJ卡了常数?

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#define eps 1e-10
#define fastcall __attribute__((optimize("-O3")))
#define IL __inline__ __attribute__((always_inline))
using namespace std;

const int maxn=162;
int n,cnt=0;
int d[maxn];
struct OP{
	int L,R;
}c[maxn];
double g[maxn];
double f[82][82];

fastcall IL int Get_pos(int v){
	int L=1,R=cnt;
	while(L<R){
		int mid=L+((R-L+1)>>1);
		if(d[mid]<=v)L=mid;
		else R=mid-1;
	}return L;
}
double Min(double L,double R){return L<R?L:R;}
double Max(double L,double R){return L>R?L:R;}
fastcall IL double Get_win(int L,int R,int i){
	if(c[i].L>=L)return 0;
	return (double)(Min(c[i].R,L)-c[i].L)/(c[i].R-c[i].L);
}
fastcall IL double Get_lose(int L,int R,int i){
	if(c[i].R<=R)return 0;
	return (double)(c[i].R-Max(c[i].L,R))/(c[i].R-c[i].L);
}
fastcall IL double Get_in(int L,int R,int i){
	if(c[i].L>=R||c[i].R<=L)return 0;
	return (double)(Min(c[i].R,R)-Max(c[i].L,L))/(c[i].R-c[i].L);
}
fastcall IL void Get_f(int L,int R,int now){
	double P=(double)(R-L)/(c[now].R-c[now].L);
	memset(f,0,sizeof(f));f[0][0]=1;
	for(int i=1;i<=n;++i){
		if(i==now)continue;
		double p1=Get_win(L,R,i);
		double p2=Get_lose(L,R,i);
		double p3=Get_in(L,R,i);
		for(int j=i;j>=0;--j){
			for(int k=i-j;k>=0;--k){
				f[j][k]=f[j][k]*p1;
				if(j>=1)f[j][k]=f[j][k]+f[j-1][k]*p2;
				if(k>=1)f[j][k]=f[j][k]+f[j][k-1]*p3;
			}
		}
	}
	for(int i=0;i<n;++i){
		for(int j=0;j<n-i;++j){
			double tmp=f[i][j];
			if(fabs(tmp)<eps)continue;
			tmp=tmp*P/(j+1);
			for(int k=0;k<=j;++k){
				g[i+k]=g[i+k]+tmp;
			}
		}
	}return;
}

int main(){
	freopen("gg.in","r",stdin);
	freopen("gg.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d%d",&c[i].L,&c[i].R);
		d[++cnt]=c[i].L;d[++cnt]=c[i].R;
	}sort(d+1,d+cnt+1);
	cnt=unique(d+1,d+cnt+1)-d-1;
	for(int i=1;i<=n;++i){
		memset(g,0,sizeof(g));
		int L=Get_pos(c[i].L),R=Get_pos(c[i].R);
		for(int j=L;j<R;++j)Get_f(d[j],d[j+1],i);
		for(int j=0;j<n;++j)printf("%.6lf ",g[j]);
		printf("\n");
	}return 0;
}

最近两天的题目没什么好说的QAQ

都是很基础的东西,推一推就可以写了

基本上拍过了就A了QAQ

概率还是弱,如果上午一遍写对的话就AK了

有时间补补概率。。

时间: 2024-10-14 09:46:01

6.19 考试修改+总结的相关文章

5.28 考试修改+总结

今天又是一个悲伤的故事,所有排名比我高的人第一题都A了 而我第一题爆零了 但是开心的事情是:第一题没有说是简单图,所以题解是错的 不管怎么样,将错就错吧 今天下午断网了,所以这时候才写blog 第一题 由于题目中没有给出欧拉图的概念,所以我完全不知道它在说啥,于是就爆零了 然后欧拉图就是存在欧拉回路的简单图,具有以下特点: 1.联通 2.度数都是偶数 显然我们将错就错看题目的话,把欧拉图数目*(n*(n-1)/2+1)就可以得到答案了 然后我们很容易知道度数均为偶数的图的数目是2^((n-1)*

6.15 考试修改+总结

昨天考崩了QAQ 几乎写全了暴力分,然而并没有什么卵用 因为只要A掉一道题就比我分高了,比我分高的也至少A掉了一道题QAQ 感觉到一丝淡淡的忧桑 貌似THUSC最后听讲课的那些人几乎都A了两题 看来我的THUSC果然只是RP好啊 第一题 显然选色数最少的颜色,设颜色数为m 考虑存在某个点的方案数,设这个点到k距离i个点 则方案数为(n-1-i)!/ ((m-i)!*j!*k!……) j,k等是其他颜色的色数 总方案也是非常好算的,这样我们就可以计算每个点对于期望的贡献了 这样做是O(n^2)的

5.26 考试修改+总结

论写5K+的代码在只有样例的条件下都可以调对 由此可见,勇气才是成功的关键 先放题解吧 第一题上午写的暴力不小心忘记题目换根之后还会染色了 然后就挂成了5分QAQ 有很大的部分分是SDOI染色,还有一部分是旅行 但是考试犯懒没有写 很容易发现任何一种颜色在树上都是连续的一段 那么我们不妨这么定义,如果一条边两端颜色不相同,我们定义为虚边,会对子树每个答案产生+1的贡献 如果两端颜色相同,我们定义为实边,不会产生贡献 不难发现,这样定义后的实边和虚边的性质和LCT的定义是一样的 我们考虑使用LCT

2019.3.18考试&amp;2019.3.19考试

2019.3.18 C O D E T1 树上直接贪心,环上for一遍贪心 T2 正反都做一遍DP T3 观察到顺序不影响答案,分块打标记 2019.3.19 肥肠爆芡,因为沙茶博主昨天在学校的煞笔食堂吃坏了肚子,所以这场考试咕咕了 我佛了 一定补这两场.jpg 原文地址:https://www.cnblogs.com/ydnhaha/p/10558495.html

6.3 考试修改+总结

今天下午考试被FFT和数论题目翔了一脸QAQ 做的是Newscafe杯的题目 第一题 异化多肽 显然构造多项式f 答案是f+f^2+f^3…… 化简一下得1/(1-f) 之后多项式求逆即可 考试的时候推了好久的多项式求逆的式子(感觉自己什么都忘光了 #include<cstdio> #include<cstring> #include<iostream> #include<cstdlib> #include<algorithm> #define

6.11 考试修改+总结

第三题至今没敢写,感觉好恐怖QAQ 今天考得好糟糕 第一题只写了10分的暴力+(k=1)20分的网络流 后来题解告诉我k>1的时候可以分治到k=1,每层分治解决方法是同k=1的 考试的时候没有注意到2^k这个比较神奇的可以分治的性质 而且自己考场上丝薄了,没有发现因为是二分图可以直接跑欧拉回路的性质,而是裸套网络流模型 第二题其实已经接近想出了题解 自己考试的时候成功证明了暴力的复杂度是线性的 但是没有想到如何寻找0-1对,然后就只能暴力用Splay维护1所在的位置了 默默祈祷数据不要太卡我的做

6.10 考试修改+总结+颓废记

昨天晚上得到了非常不爽的消息,zcg要去给高一讲课,而我并不能去 虽然什么事情并不能都顺着我的心意来吧,但是这件事情真是让人越想越不痛快 要知道,我从去年就一直期待着给高一讲课呢 所以今天考试非常不开心,一般这个时候我会选择爆零的 但是想了想觉得爆零太难看,就看了看好像第一题可做 在教学楼里颓废了好久然后吃了点东西,用最后的时间码完了第一题 (反正二.三题我没看出来怎么做,所以暴力也不想写了 然后惊讶的是,只有第一题程序的窝rank1了QAQ 先放题解吧 第一题: 首先我们注意到转置的实质是某个

5.27 考试修改+总结

这是一个悲伤的故事 上午写manacher的时候往里面加#号,然后统计有效字符的个数 然后我就开始模拟,一个长度为6的串我都能数错有多少个有效字符 我把2个字符数成了3个!然后暴力就挂掉了5分.. 为什么这几天的暴力总是会挂掉,真是奇怪(看来是最近自己内心不太稳了 (大概是被那个梦吓得吧QAQ) 今天又A了两道题目,感觉天天都是两道正解+挂掉的暴力QAQ 先放题解吧 第一题是之前数位DP坑掉的题目,然后今天尝试着写了写,感觉不是很难 但是并不是用数位DP做的 先考虑加密的情况,我们只需要统计每一

5.25 考试+修改

论改题只用两分钟的速度QAQ 其实就是换了个数组名字,加上加了一句话 第一题: 首先考虑k=1的情况,考虑构造转移矩阵A ans*(A^0+A^1+……+A^(n-1)) 然后括号里的式子等比数列求和一下 是(A^0-A^n)/(A^0-A^1) 涉及到除法,手动矩阵求逆就可以了 然后这个式子就变成了一个矩阵 我们考虑k>1的情况,发现扩维不过就是又乘了一次这个矩阵 然后把这个矩阵自乘k次即可 (考试的时候犯傻,没有想到k>1的时候直接自乘k次就可以了,下午加了一句话就A了) #include