6.11 考试修改+总结

第三题至今没敢写,感觉好恐怖QAQ

今天考得好糟糕

第一题只写了10分的暴力+(k=1)20分的网络流

后来题解告诉我k>1的时候可以分治到k=1,每层分治解决方法是同k=1的

考试的时候没有注意到2^k这个比较神奇的可以分治的性质

而且自己考场上丝薄了,没有发现因为是二分图可以直接跑欧拉回路的性质,而是裸套网络流模型

第二题其实已经接近想出了题解

自己考试的时候成功证明了暴力的复杂度是线性的

但是没有想到如何寻找0-1对,然后就只能暴力用Splay维护1所在的位置了

默默祈祷数据不要太卡我的做法,结果最后只比裸暴力分多10分,只是悲桑

考后跟zcg交流一下发现维护一下hash值之后每次二分就可以找到0-1对了(考场上在想什么系列

但是这样会T或者WA(因为貌似卡自然溢出?瞎改几个base就可以了

还有一种做法是在线段树上直接劈开区间,然后如果哈希值相等的区间就不递归,否则递归下去改

时间复杂度略微有些玄学,但是跑的比hash+二分快

自己写的貌似会T一个点,不过懒得玩常数优化了

第三题貌似是弱化版的火龙果

不过LCT要维护一些奇怪的东西,考试的时候没有想出来怎么维护

后来看题解发现维护的方法类似疯狂的重心,LCT维护子树和

每次暴力删最大边看看是否可以不丢失解

但是感觉要码这样一坨东西好鬼畜啊

被莫名卡了常数,丢了20分的暴力分QAQ

最后貌似交到OJ上rank2?

%%%zcg

第一题代码:

写欧拉回路的时候写的比较鬼畜,但也只能这样写来保证O(m)的性质了(YY了好久,感谢jkxing

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

const int maxn=400010;
int n,m,k,T;
int deg[maxn];
struct Edge{
	int u,v,id;
}c[maxn],Q1[maxn],Q2[maxn];
int Ans[maxn];
int h[maxn],cnt=0;
bool vis[maxn];
int check[maxn],tim;
int st[maxn],top=0;
struct edge{
	int to,next,w;
}G[maxn];

void add(int x,int y,int z=0){
	++cnt;G[cnt].to=y;G[cnt].next=h[x];G[cnt].w=z;h[x]=cnt;
	vis[cnt]=false;
}
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 Get_euler(int u,int f){
	check[u]=tim;
	for(int i=h[u];i;i=h[u]){
		if(vis[i]){h[u]=G[i].next;continue;}
		int v=G[i].to;
		vis[i]=vis[i^1]=true;
		G[i].w=G[i^1].w=f;
		h[u]=G[i].next;
		Get_euler(v,f^1);
	}return;
}
void Solve(int L,int R,int k){
	if(!k)return;
	cnt=1;tim++;top=0;
	for(int i=L;i<=R;++i){
		int u=c[i].u,v=c[i].v;
		add(u,v);add(v,u);
		if(check[u]!=tim)check[u]=tim,st[++top]=u;
		if(check[v]!=tim)check[v]=tim,st[++top]=v;
	}tim++;
	for(int i=1;i<=top;++i){
		if(check[st[i]]!=tim)Get_euler(st[i],0);
	}
	int l1=0,l2=0;
	for(int i=L;i<=R;++i){
		int now=(i-L+1)<<1;
		int u=c[i].id;
		h[c[i].u]=h[c[i].v]=0;
		Ans[u]=(Ans[u]<<1)|G[now].w;
		if(G[now].w)Q2[++l2]=c[i];
		else Q1[++l1]=c[i];
	}
	for(int i=1;i<=l1;++i)c[L+i-1]=Q1[i];
	for(int i=1;i<=l2;++i)c[L+l1+i-1]=Q2[i];
	Solve(L,L+l1-1,k-1);Solve(L+l1,R,k-1);
}

int main(){
	int __size__=128<<20;
	char *__p__=(char*)malloc(__size__)+__size__;
	__asm__("movl %0, %%esp\n"::"r"(__p__));
	while(scanf("%d%d",&n,&m)==2){
		memset(deg,0,sizeof(deg));
		for(int i=1;i<=m;++i){
			read(c[i].u);read(c[i].v);
			c[i].id=i;
			deg[c[i].u]++;deg[c[i].v]++;
		}
		for(k=1;k;++k){
			int mk=(1<<k);
			bool flag=false;
			for(int i=1;i<=n;++i)if(deg[i]%mk!=0||!deg[i]){flag=true;break;}
			if(flag)break;
		}k--;
		if(!k)printf("-1\n");
		else{
			memset(Ans,0,sizeof(Ans));
			Solve(1,m,k);
			printf("%d\n",k);
			for(int i=1;i<=m;++i)printf("%d ",Ans[i]+1);
			printf("\n");
		}
	}return 0;
}

第二题代码:

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

typedef long long LL;
const int maxn=1000010;
const int base=13331;
int n,m,type,L,R,len,p,x,y;
char s[maxn];
int sum[maxn<<2];
LL xp[maxn];
LL h[maxn<<2];

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){
		h[o]=s[L];
		sum[o]=h[o]-‘0‘;
		return;
	}
	int mid=(L+R)>>1;
	int l=(o<<1),r=(l|1);
	build(l,L,mid);build(r,mid+1,R);
	h[o]=h[l]*xp[R-mid]+h[r];
	sum[o]=sum[l]+sum[r];
}
void UPD(int o,int L,int R){
	if(L==R){
		h[o]^=1;
		sum[o]^=1;
		return;
	}
	int mid=(L+R)>>1;
	int l=(o<<1),r=(l|1);
	if(p<=mid)UPD(l,L,mid);
	else UPD(r,mid+1,R);
	h[o]=h[l]*xp[R-mid]+h[r];
	sum[o]=sum[l]+sum[r];
}
LL ask(int o,int L,int R){
	if(L>=x&&R<=y)return h[o];
	int mid=(L+R)>>1;
	if(y<=mid)return ask(o<<1,L,mid);
	else if(x>mid)return ask(o<<1|1,mid+1,R);
	else{
		LL A=ask(o<<1,L,mid);
		LL B=ask(o<<1|1,mid+1,R);
		return A*xp[min(y,R)-mid]+B;
	}
}
int ask_S(int o,int L,int R){
	if(L>=x&&R<=y)return sum[o];
	int mid=(L+R)>>1;
	if(y<=mid)return ask_S(o<<1,L,mid);
	else if(x>mid)return ask_S(o<<1|1,mid+1,R);
	else return ask_S(o<<1,L,mid)+ask_S(o<<1|1,mid+1,R);
}

int main(){
	freopen("and.in","r",stdin);
	freopen("and.out","w",stdout);
	read(n);read(m);
	scanf("%s",s+1);
	xp[0]=1;
	for(int i=1;i<=n;++i)xp[i]=xp[i-1]*base;
	build(1,1,n);
	while(m--){
		read(type);
		if(type==1){
			read(L);read(R);read(len);
			int l=1,r=len;
			while(true){
				while(l<r){
					int mid=(l+r)>>1;
					x=L;y=L+mid-1;
					LL A=ask(1,1,n);
					x=R;y=R+mid-1;
					LL B=ask(1,1,n);
					if(A==B)l=mid+1;
					else r=mid;
				}
				x=L+r-1;y=R+r-1;
				int A=s[x]-‘0‘,B=s[y]-‘0‘;
				if(A==B)break;
				if(A==1)s[x]=‘0‘,p=x,UPD(1,1,n);
				else s[y]=‘0‘,p=y,UPD(1,1,n);
				l=r;r=len;
			}
		}else if(type==2){
			read(L);p=L;
			if(s[L]==‘1‘)s[L]=‘0‘;
			else s[L]=‘1‘;
			UPD(1,1,n);
		}else{
			read(L);read(R);read(len);
			x=L;y=R;
			int now=ask_S(1,1,n);
			if(len==1)printf("%d\n",now);
			else printf("%d\n",R-L+1-now);
		}
	}return 0;
}

第三题看看zcg他们能不能搞出来吧

感觉自己要写的话一个晚上药丸啊

时间: 2024-12-09 19:25:11

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

9.11考试总结

# 9.11考试总结 细胞分裂 数学题目,因式分解后直接判断输入数据是否含有m1中分解出来的数,然后储存需要时间最大值中的最小值 #include<bits/stdc++.h> #define open(s) freopen(s".in", "r", stdin);// freopen(s".out", "w", stdout); #define IL inline #define ull unsigned lon

10.11考试总结

10.11考试总结 全是DP实际上发现暴力也能有部分分....... 三角形牧场 DP......当时总是感觉不像啊 需要处理的就是枚举三角形边长可能出现的情况.因为周长在输入端时候就可以确定了,所以只需要通过枚举两条边就可以强行算出第三条边..... 所以就省空间+时间.... f[0][0] = 1; for (int i=1; i<=n; ++i) for(int j=half; j>=0; j--) for(int k=j; k>=0; k--) if(j >= d[i]

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

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.10 考试修改+总结+颓废记

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

5.27 考试修改+总结

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

6.19 考试修改+总结

QAQ 又是一套水题集合 然后忧伤的故事是老师把时间调到了四个小时半 我又因为想要出道题花了半个小时写了一些其他的东西 然后最后没有写完题!QAQ 不然第三题可能多拿点分 上午的时候把所有题目的正解都想了出来 唯一美中不足的是自己想的第三题是O(n^4*300)的是时间复杂度 实际上离散化区间之后只会有n个区间,时间复杂度就是O(n^5)了QAQ 先说题解把 第一题 决战圆锥曲线 显然给定你的那个函数a*x+b*y+c*x*y对于x,y是相对等价的 又因为题目的输入具有随机性,显然可以通过维护线