首页 > 其他分享 >atcoder 杂题 #02

atcoder 杂题 #02

时间:2024-12-07 10:59:12浏览次数:11  
标签:02 atcoder return int tot next second 杂题 fo

atcoder 杂题 #02

arc065_b

对两种边分别建图求并查集,其实就是求有多少个点满足两个图都在同一个并查集。

可以把一个点的并查集标号扔进 map<pair<int,int>,int> 里,就能统计个数了。

时间复杂度 \(O(n\log n)\)。

这道题容易往错误的方向想或者想复杂。

AC 代码:

const int N=2e5+5;
int n,m,p;
int fa[N];
int getfa(int x){
	if(fa[x]==x)return x;
	return fa[x]=getfa(fa[x]);
}
int fa2[N];
int getfa2(int x){
	if(fa2[x]==x)return x;
	return fa2[x]=getfa2(fa2[x]);
}
map<pair<int,int>,int> mp;
signed main(){
	read(n,m,p);
	fo(i,1,n)fa[i]=i,fa2[i]=i;
	fo(i,1,m){
		int u,v;
		read(u,v);
		u=getfa(u),v=getfa(v);
		if(u!=v)fa[u]=v;
	}
	fo(i,1,p){
		int u,v;
		read(u,v);
		u=getfa2(u),v=getfa2(v);
		if(u!=v)fa2[u]=v;
	}
	fo(i,1,n)mp[{getfa(i),getfa2(i)}]++;
	fo(i,1,n){
		write(mp[{getfa(i),getfa2(i)}],' ');
	}
	return 0;
}

arc137_b

我没有想到这样神奇的水题。

考虑一个要翻转的区间 \([l,r]\),把一个端点移动一个位置,那么贡献的变化量为 1。

那么求出贡献的最大值和最小值,最大值的区间一定能通过不断移动一单位的端点变成最小值的区间,那么最大值到最小值都能取遍。

于是用前缀和求贡献变化量的最大值 \(Max\) 和最小值 \(Min\)。答案就是 \(Max-Min+1\)。

而翻转一段区间的变化量就是 \(len-2*cnt\),即 \((r-2*cnt_r)-(l-1-2*cnt_{l-1})\)。

时间复杂度 \(O(n)\)。

AC 代码:

const int N=3e5+5;
int n;
int a[N];
int s[N];
int mx=0,mn=0;
int Max=0,Min=0;
signed main(){
	read(n);
	fo(i,1,n){
		read(a[i]);
		s[i]=s[i-1]-2*a[i];
	}
	fo(i,1,n){
		s[i]+=i;
		mx=max(mx,s[i]-Min);
		mn=min(mn,s[i]-Max);
		Max=max(Max,s[i]);
		Min=min(Min,s[i]);
	}
	write(mx-mn+1);
	return 0;
}

abc287_f

一眼树上背包,并且看到 \(n\le 5000\) 是可以通过的。

我们要注意在限制枚举范围的情况下,树上背包的复杂度是 \(O(n^2)\) 的。

设 \(f_{i,j}\) 表示选择点 \(i\) 且子树内有 \(j\) 个连通块的方案数,\(g_{i,j}\) 表示不选择点 \(i\) 的方案数。

\(f\to g,g\to g,g\to f\) 都是直接把连通块个数相加,\(f\to f\) 则把连通块个数相加后减 1。

注意要先转移再把 \(sz\) 加上复杂度才是正确的。

AC 代码:

const int N=5005;
const int mod=998244353;
int n;
vector<int> G[N];
int f[N][N],g[N][N];
int sz[N];
void dfs(int x,int y){
	g[x][0]=1;
	f[x][1]=1;
	sz[x]=1;
	for(int v:G[x]){
		if(v==y)continue;
		dfs(v,x); 
		fd(i,sz[x],0){
			fd(j,sz[v],1){
				g[x][i+j]=(g[x][i+j]+(ll)g[x][i]*g[v][j])%mod;
				g[x][i+j]=(g[x][i+j]+(ll)g[x][i]*f[v][j])%mod;
				f[x][i+j]=(f[x][i+j]+(ll)f[x][i]*g[v][j])%mod;
				f[x][i+j-1]=(f[x][i+j-1]+(ll)f[x][i]*f[v][j])%mod;	
			}
		}
		sz[x]+=sz[v];
	}
}
signed main(){
	read(n);
	fo(i,1,n-1){
		int u,v;
		read(u,v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1,0);
	fo(i,1,n){
		write((f[1][i]+g[1][i])%mod,'\n');
	}
	return 0;
}

abc308_g

考虑对每个数建出 01-Trie。对于一个数 \(x\),我们找一个数 \(y\) 要使异或和最小,那么 \(\text{LCA}(x,y)\) 的深度要尽可能大,即高位连续相等的位要尽可能多。而如果 \(x,y\) 在 01-Trie 上低位还有分支,那么 \(x\oplus y\) 肯定不是最优的。

于是发现,答案就是 01-Trie 上相邻两个叶子的异或和的最小值,又发现 01-Trie 上相邻两个叶子在值域上也相邻。

于是用 set 维护当前黑板上的数,同时也能方便得到相邻的数。再用一个 set 维护出相邻两个数的异或和。

可以使用 prevnext 方便地得到前驱和后继的迭代器。

时间复杂度 \(O(Q\log Q)\)。

int Q;
const int N=3e5+5;
int tot;
int a[N];
set<pair<int,int> > s;
set<pair<int,pair<int,int>> > t;
void del(int x,int y){
	if(x>y)swap(x,y);
	t.erase({a[x]^a[y],{x,y}});
}
void add(int x,int y){
	if(x>y)swap(x,y); 
	t.insert({a[x]^a[y],{x,y}});
}
signed main(){
	cin>>Q;
	while(Q--){
		int opt;
		cin>>opt;
		if(opt==1){
			++tot;
			cin>>a[tot];
			auto i=s.insert({a[tot],tot}).first;
			if(i!=s.begin())add(prev(i)->second,tot);
			if(next(i)!=s.end())add(next(i)->second,tot);
			if(i!=s.begin()&&next(i)!=s.end())del(prev(i)->second,next(i)->second);
		}
		else if(opt==2){
			int x;
			cin>>x;
			auto i=s.lower_bound({x,0});
			if(i!=s.begin())del(prev(i)->second,i->second);
			if(next(i)!=s.end())del(next(i)->second,i->second);
			if(i!=s.begin()&&next(i)!=s.end())add(prev(i)->second,next(i)->second);
			s.erase(i);
		}
		else{
			cout<<(t.begin()->first)<<'\n'; 
		}
	}
	return 0;
}

标签:02,atcoder,return,int,tot,next,second,杂题,fo
From: https://www.cnblogs.com/dccy/p/18591898

相关文章

  • NOIP2024游记
    2024NOIP总结Day016、20、22、24、25、38、40、41、42、43、44、46、47、49、53因为我们就是在本校考,下午到了机房之后就去明儿考试的座位上看了一下,打了一下键盘感觉比较正常,祈祷明儿吧。我们三点半就放了,肩膀不是很舒服,然后没有跟着停课所以没反应过来,放了之后人有点懵,本来......
  • 参加【2025年3月】全国CTF夺旗赛-从零基础入门到竞赛,看这一篇就稳了!
    ......
  • 网络安全(黑客)小白自学必看—最新寒假学习计划【2025年】
    ......
  • 20241206: 999. 可以被一步捕获的棋子数
    给定一个 8x8 的棋盘,只有一个 白色的车,用字符 'R' 表示。棋盘上还可能存在白色的象 'B' 以及黑色的卒 'p'。空方块用字符 '.' 表示。车可以按水平或竖直方向(上,下,左,右)移动任意个方格直到它遇到另一个棋子或棋盘的边界。如果它能够在一次移动中移动到棋子的方格,则能......
  • 20222324 石国力 《网络与系统攻防技术》 实验五
    1.实验目的(1)从www.besti.edu.cn、baidu.com、sina.com.cn中选择一个DNS域名进行查询,获取如下信息:·DNS注册人及联系方式·该域名对应IP地址·IP地址注册人及联系方式·IP地址所在国家、城市和具体地理位置PS:使用whois、dig、nslookup、traceroute、以及各类在线和离线工具......
  • 20222318 2024-2025-1 《网络与系统攻防技术》实验五实验报告
    1.实验内容(1)从www.besti.edu.cn、baidu.com、sina.com.cn中选择一个DNS域名进行查询,获取如下信息:DNS注册人及联系方式该域名对应IP地址IP地址注册人及联系方式IP地址所在国家、城市和具体地理位置PS:使用whois、dig、nslookup、traceroute、以及各类在线和离线工具......
  • 题解:AtCoder Beginner Contest AT_abc380_d ABC380D Strange Mirroring
    题目大意给定一个字符串$S$,执行$10^{100}$次以下操作:首先,令字符串$T$为字符串$S$中所有大写字母变为小写字母,小写字母变为大写字母的结果。其次,将$T$拼接在$S$后面。接下来,有一些询问:请输出在所有操作执行完成之后$S$的第$K$个字母。思路乍一看,好大的数......
  • 题解:AtCoder Beginner Contest AT_abc373_d ABC373D Hidden Weights
    题目传送门题目翻译给你一个$N$个点,$M$条边的有向图,其中边有边权。现在让你给每一个点设置一个点权$a$,使得对于任意两点$x$和$y$,如果$x$到$y$有一条边,边权为$w$,那么需要满足$a_y-a_x=w$。现在让你输出一组合法的分配方案,题目保证存在,输出任意一组都行。思路1(注意......
  • P9751 [CSP-J 2023] 旅游巴士
    $P9751$部分分思路题目要求时间必须是$k$的非负整数倍,所以想到了升维。这样就变成了一道分层图最短路的题目。用BFS算法可以拿到$A_i=0$的$35$分。满分思路其实部分分的思路已经很接近正解了,想要拿到满分只需要做一点小小的调整。虽然说不能在路上停留,但是......
  • 20222409 2021-2022-2 《网络与系统攻防技术》实验七实验报告
    1.实验内容1.1本周学习内容学习了SET和Ettercap工具的使用,掌握了ARP污染和DNS欺骗的攻击原理与过程。了解钓鱼网站的工作原理及防范措施。学习了Web安全基础,掌握前后端概念和常用技术(如前后端区别、java和js区别、前后端编程语言的特点和应用场景等)。深入理解SQL注入和XSS......