首页 > 其他分享 >CF题解

CF题解

时间:2023-04-18 19:44:06浏览次数:46  
标签:int 题解 可以 CF long ans now

E. Replace the Numbers 1900 思维

https://codeforces.com/problemset/problem/1620/E
题解:正着做比较困难,我们可以考虑从后往前做。一个数会被变成什么样子是取决于其后的2操作。2操作可以等价为一个变换,而位置越后的2操作相较前面的2操作起着决定性作用,故从后往前遍历时前面的操作只能在已存在的变换上进行,比如u->v,只能将u->f(v),而u不变是因为其时间轴上更靠前,所以它的优先级更高。故我们遍历即可得到答案。
另一种直观的理解可以把其按时间分为一个分部图,每一部分有n个点,当有变换时改变映射。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+10;
struct node{
	int u,v,w;
}a[N];
int f[N],b[N];
signed main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++){
		int k,x,y;cin>>k;
		if(k==1){
			cin>>x;
			a[i]={1,x,0};
		}
		else{
			cin>>x>>y;
			a[i]={2,x,y};
		}
	}
	for(int i=1;i<N;i++){
		f[i]=i;
	}
	int t=0;
	for(int i=n;i>=1;i--){
		auto [u,v,w]=a[i];
		if(u==1){
			b[++t]=f[v];
		}
		else{
			f[v]=f[w];
		}
	}
	for(int i=t;i>=1;i--)
	cout<<b[i]<<" ";
}

D. Infinite Set 1800

https://codeforces.com/contest/1635/problem/D
题解:4可以看作是二进制左移2位,2+1可以看作左移一位+1,我们可以对所有数从小到大排序,令二进制长度位p时的答案为f(p)(由于对于一个数x而言,其变换后的数必然互不相同,证明很显然),而x可以变成2x+1,4x两种形式,故f(p)=f(p+1)+f(p+2)+1,可以预处理。对于a[i]若其不能被其之前的数表示,则其所产生的所有数都没有出现过,否则a[i]一定可以被表示。而对于一个数x,其每次变换都至少*2,故可以logn判断其先前数是否出现过。最后加上所有答案即可,复杂度为O(nlogn).

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10,mod=1e9+7;
map<int,int> v;
int a[N],f[N+100];
queue<int> q;
signed main(){
	f[1]=2,f[0]=1;
	for(int i=2;i<=N;i++){
		f[i]=(f[i-1]+f[i-2]+1)%mod;
	}
	int n,p;cin>>n>>p;
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a+1,a+n+1);
	int ans=0,res=0;
	for(int i=1;i<=n;i++){
		int cnt=0,x=a[i],ok=1;
		while(x>0){
			int now=0;
		while(x%2&&x>0){
			x=(x-1)/2;
			if(v[x]) ok=0;
			now=1;
		}
		while(x%4==0&&x>0){
			x/=4;
			if(v[x]){
				ok=0;break;
			}
			now=1;
		}
		if(!ok) break;
		if(!now) break;
		}
		if(!ok) continue;
		v[a[i]]=1;
		x=a[i];cnt=0;
		while(x){
			cnt++;x/=2;
		}
		if(cnt>p) continue;
		ans=(ans+f[p-cnt])%mod;
	}
	cout<<ans;
}

E. Boring Segments 2100 线段树 2 pointers gq!

https://codeforces.com/contest/1555/problem/E
题解:对于有两个值需要考虑的时候,我们可以选择二分或双指针,我们可以枚举最小值x,试确定最小的可能最大值,定为f(x),显然f(x)是不减的。那么我们可以考虑双指针,我们把线段按照w从小到大排序,每次删去小于左指针的,然后不断增大右指针直到1-m每个区间都被覆盖。如何增删区间呢?我们可以使用线段树,节点i表示[i,i+1]上被区间经过了多少次,区间最小值>0时即满足题意,可logm维护,总复杂度nlogn+nlogm。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10;
struct node{
	int l,r,w;
}t[N*4];
struct qwq{
	int u,v,w;
}b[N];
bool cmp(qwq x,qwq y){
	return x.w<y.w;
}
int lz[N*4],a[N];
void build(int p,int l,int r){
	t[p].l=l,t[p].r=r;
	if(t[p].l==t[p].r){
		t[p].w=0;return;
	}
	int mid=(l+r)/2;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	t[p].w=min(t[p*2].w,t[p*2+1].w);
}
void spread(int p){
	if(lz[p]==1e18) return;
	t[p*2].w+=lz[p];
	t[p*2+1].w+=lz[p];
	lz[p*2]+=lz[p];
	lz[p*2+1]+=lz[p];
	lz[p]=0;
}
void change(int p,int l,int r,int k){
	if(l<=t[p].l&&t[p].r<=r){
		t[p].w+=k;
		lz[p]+=k;
		return;
	}
	spread(p);
	int mid=(t[p].l+t[p].r)/2;
	if(l<=mid) change(2*p,l,r,k);
	if(r>mid) change(2*p+1,l,r,k);
	t[p].w=min(t[p*2].w,t[p*2+1].w);
}
int ask(int p,int l,int r){
	if(t[p].l>=l&&t[p].r<=r){
		return t[p].w;
	}
	spread(p);
	int mid=(t[p].l+t[p].r)/2,res=1e18;
	if(l<=mid) res=min(ask(p*2,l,r),res);
	if(r>mid) res=min(ask(p*2+1,l,r),res);
	return res;
}
signed main(){
	int n,m;cin>>n>>m;
	for(int i=1;i<=n;i++){
		int l,r,w;cin>>l>>r>>w;
		b[i]={l,r,w};
	}
	build(1,1,m-1);
	sort(b+1,b+n+1,cmp);
	int p=1,ans=1e18;
	for(int i=1;i<=n;i++){
		if(i!=1){
		auto [u,v,w]=b[i-1];
		change(1,u,v-1,-1);
		}
		while(p<=n){
			if(ask(1,1,m-1)==0){
				int x=b[p].u,y=b[p].v;
				change(1,x,y-1,1);
				p++;
			}
			else{
				break;
			}
		}
		if(ask(1,1,m-1)>0)
		ans=min(ans,b[p-1].w-b[i].w);
	}
	cout<<ans;
}

标签:int,题解,可以,CF,long,ans,now
From: https://www.cnblogs.com/wjhqwq/p/17330853.html

相关文章

  • CF 1360E-Polygon,1300,思维题
    CF1360E-Polygon如果一个1不是在最右边或最下边,则一定有一个1在他的紧邻着的下边或右边,否则不合法。太妙了。#include<iostream>usingnamespacestd;constintN=1e2+10;intT,n;chara[N][N];intmain(){cin>>T;while(T--){......
  • CF449D Jzzhu and Numbers
    CF449DJzzhuandNumbers黄金定律:给定序列求答案,但答案与序列顺序无关的题目,要么考虑把序列转权值序列,要么对序列排序。二进制题按大小排序看起来就没啥用,那就转成权值序列。即,设\(c(i)\)表示\(i\)在\(a\)中的出现次数。同时设\(V\)为\(a\)的值域。然后直接算发现不......
  • 【题解】P6292 区间本质不同子串个数
    原题链接区间本质不同子串个数题目描述给定一个长度为\(n\)的字符串\(S\),\(m\)次询问由\(S\)的第\(L\)到第\(R\)个字符组成的字符串包含多少个本质不同的子串。定义两个字符串\(a,b\)相同当且仅当\(|a|=|b|\)并且对于\(i\in[1,|a|]\)都有\(a_i=b_i\)。输入......
  • 十五天精通WCF——终结篇 那些你需要注意的坑
         终于一路走来,到了本系列的最后一篇了,这一篇也没什么好说的,整体知识框架已经在前面的系列文章中讲完了,wcf的配置众多,如果不加一些指定配置,你可能会遇到一些灾难性的后果,快来一睹为快吧。 一:第一个大坑【数据传输量】我们使用wcf的目的,就是用来进行分......
  • 超级码力初赛第二场 五字回文 题解
    题目描述小栖最近很喜欢回文串,由于小栖的幸运数字是5,他想知道形似“abcba"的回文串在他给定的字符串中的数量s.length<=10^6字符串s只包含小写字母示例示例1:输入:s="abcba"输出:1示例2:输入:s="abcbabcccb"输出:2解释:形似”abcba“的字符串有”abcba“和”cbab......
  • CF题解
    D.GuessthePermutation2000逆序性质二分https://codeforces.com/contest/1589/problem/D题解:首先我们可以二分查找i的位置:当1->x逆序对>0,则在i右,否则在左,log(n)次询问。找到i的位置后,我们发现逆序对有如下性质,i->j-1的数量和i+1->j-1的数量差为j-1-i,故我们可以询问i+1->n......
  • CF 476B Dreamoon and WiFi
    DreamoonandWiFi一个简答的组合数学题。开始想弄一个很妙的做法,但是我理解不了,或者说理解困难,半天没搞出来,然后试着还是用朴素好想的做法做吧,结果马上做出来了。选择朴素的做法时还是有个地方想不清楚,分类讨论+举例一下子清楚了。......
  • GDOU-CTF-2023新生赛Pwn题解与反思
    第一次参加CTF新生赛总结与反思因为昨天学校那边要进行天梯模拟赛,所以被拉过去了。16点30分结束,就跑回来宿舍开始写。第一题和第二题一下子getshell,不用30分钟,可能我没想那么多,对比网上的WP,自己和他们有点不太一样,比较暴力。大概17点10的时候,写第三题,可能自己第一次遇到随机数问......
  • elementui select下来内容过长问题解决方案
    :popper-append-to-body="false"必写自定义显示<divclass="select-flow">{{dict.declareConditions}}</div>自定义css样式el-option添加title属性 <el-selectv-model="formData.declCondition"placeholder="请选择"sty......
  • CF1646E Power Board 题解
    题目链接:https://codeforces.com/contest/1646/problem/E题目大意:有一个\(n\timesm\)的矩阵,其中第\(i\)行第\(j\)列的格子中的数字是\(i^j\)。问:矩阵中存在多少个不同的数?解题思路:可以很明显地发现,第\(1\)行的数字全部都是\(1\),而且在其它行不会出现数值为\(1\)......