【恢复计划】CF ROUND 620 div2 简要题解

【恢复计划】CF ROUND 620 div2 简要题解

找神腮要了一个简单场

A - Two Rabbits

判断((a+b)|(x-y))​就行了

//@winlere
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>

using namespace std;
typedef long long ll;
int qr(){
	int ret=0,c=getchar();
	while(!isdigit(c)) c=getchar();
	while( isdigit(c)) ret=ret*10+c-48,c=getchar();
	return ret;
}

ll gcd(ll a,ll b){
	if(!b) return a;
	return gcd(b,a%b);
}

int main(){
	int T=qr();
	while(T--){
		ll x=qr(),y=qr(),a=qr(),b=qr();
		ll z=y-x,d=gcd(z,a+b);
		if(d==a+b) cout<<z/(a+b)<<endl;
		else cout<<"-1"<<endl;
	}
	return 0;
}

B - Longest Palindrome

因为保证的所有字符串长度都是m,因此贪心的能放就放就行(对于一个串,找是否存在它的reverse之后的串,如果有就直接放)。

但是有一个特殊情况,就是自我对称的串,这个直接放在中间就行

//@winlere
#include<iostream>
#include<set>
#include<cstring>
#include<cstdio>
#include<algorithm>

using namespace std;
const int maxn=105;
string data[maxn],ans,self;
multiset<string> s;

int main(){
	int n,m;
	cin>>n>>m;
	for(int t=1;t<=n;++t) {
		cin>>data[t];
		string f=data[t];
		reverse(f.begin(),f.end());
		auto it=s.find(f);
		if(it!=s.end()) ans=data[t]+ans+f,s.erase(it);
		else s.insert(data[t]);
	}
	for(auto t:s){
		auto f=t;
		reverse(f.begin(),f.end());
		if(f==t){
			int siz=ans.size();
			if(siz==0) ans=t;
			else ans.insert(siz/2,f);
			break;
		}
	}
	cout<<ans.size()<<endl<<ans<<endl;	
	return 0;
}


C - Air Conditioner

容易证明,任何一个时间点,可以达到的温度是一个连续的区间,因此维护这个可行区间就行。时间会延伸这个可行区间,顾客的要求会限制这个可行区间,复杂度(O(n))

//@winlere
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long ll;

int qr(){
	int ret=0,c=getchar(),f=0;
	while(!isdigit(c)) f=c=='-',c=getchar();
	while( isdigit(c)) ret=ret*10+c-48,c=getchar();
	return f?-ret:ret;			   
}
const int maxn=505;
struct Peroid{
	int l,r;
	Peroid(int a=-1e9,int b=1e9):l(a),r(b){}
	Peroid operator + (Peroid f){
		int L=max(l,f.l),R=min(r,f.r);
		if(L>R) return Peroid(1e9,-1e9);
		return Peroid(L,R);
	}
	Peroid operator + (int d){
		return Peroid(l-d,r+d)+Peroid();
	}
};

int main(){
	int T=qr();
	while(T--){
		int n=qr(),m=qr(),tim=0;
		Peroid now(m,m);
		for(int t=1;t<=n;++t){
			int cur=qr(),l=qr(),r=qr();
			Peroid cur1(l,r);
			now=now+(cur-tim)+cur1;
			tim=cur;
		}
		if(now.l<=now.r) puts("YES");
		else puts("NO");
	}
	return 0;
}


D - Shortest and Longest LIS

虽然退役多年,但还是记得一些套路。

构造一个最长的LIS,理论上界是所有连续的(<)号连接的数字都是LIS的一部分,这是上界,下面我将构造出这个上界:

初始有一个(1 2 3 dots),然后将所有(>)的连续段reverse就行了。

同样的方法,构造一个最小的LIS,理论下界是最长的连续(>)​号,这是下界,下面我将构造出这个下界

初始有一个(n n-1 dots 3 2 1)

然后把所有的(<)的连续段reverse就行了。

//@winlere
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;

const int maxn=2e5+5;
int qr(){
	int ret=0,c=getchar();
	while(!isdigit(c)&&c!='<'&&c!='>') c=getchar();
	if(c=='<')  return 0;
	if(c=='>')  return 1;
	while( isdigit(c)) ret=ret*10+c-48,c=getchar();
	return ret;
}
int data[maxn],ans[maxn];

int main(){
	int T=qr();
	while(T--){
		int n=qr();
		for(int t=1;t<n;++t) data[t]=qr();
		for(int t=1;t<=n;++t) ans[t]=n-t+1;
		for(int t=1,r=1;t<n;t=++r){
			while(r<n&&data[r]==0) ++r;
			reverse(ans+t,ans+r+1);
		}
		for(int t=1;t<=n;++t) printf("%d ",ans[t]);
		putchar('
');
		for(int t=1;t<=n;++t) ans[t]=t;
		for(int t=1,r=1;t<=n;t=++r) {
			while(r<n&&data[r]==1) ++r;
			reverse(ans+t,ans+r+1);
		}
		for(int t=1;t<=n;++t) printf("%d ",ans[t]);
		putchar('
');
	}
	return 0;
}

E - 1-Trees and Queries

由于可以重复走一个边,因此可行性之和两点之间的最短路的奇偶性有关了

//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;
int qr(){
	int ret=0,c=getchar(),f=0;
	while(!isdigit(c)) f=c=='-',c=getchar();
	while( isdigit(c)) ret=ret*10+c-48,c=getchar();
	return f?-ret:ret;
}
const int maxn=1e5+5;
vector<int> e[maxn];
void add(int a,int b){e[a].push_back(b);e[b].push_back(a);}
int lg[maxn],r[21][maxn],dep[maxn],n,m;
void dfs(int now,int last){
	r[0][now]=last; dep[now]=dep[last]+1;
	for(int t=1;t<=lg[dep[now]];++t)
		r[t][now]=r[t-1][r[t-1][now]];
	for(auto t:e[now])
		if(t^last)
			dfs(t,now);
}

int LCA(int u,int v){
	if(dep[u]<dep[v]) swap(u,v);
	for(int t=lg[dep[u]];~t;--t)
		if(dep[r[t][u]]>=dep[v])
			u=r[t][u];
	if(u==v) return u;
	for(int t=lg[dep[u]];~t;--t)
		if(r[t][u]!=r[t][v])
			u=r[t][u],v=r[t][v];
	return r[0][u];
}

int getLen(int a,int b){
	int L=LCA(a,b);
	return dep[a]+dep[b]-dep[L]-dep[L];
}

int getAns(int a,int b,int x,int y,int k){
	int L1=getLen(a,b),L2=getLen(a,x)+getLen(y,b)+1;
	if( (!((L1^k)&1))&&L1<=k ) return 1;
	if( (!((L2^k)&1))&&L2<=k ) return 1;
	return 0;
}

int main(){
	for(int t=2;t<maxn;++t) lg[t]=lg[t>>1]+1;
	n=qr();
	for(int t=1;t<n;++t) add(qr(),qr());
	dfs(1,0);
	m=qr();
	for(int t=1;t<=m;++t){
		int x=qr(),y=qr(),a=qr(),b=qr(),k=qr();
		puts(getAns(a,b,x,y,k)||getAns(a,b,y,x,k)?"YES":"NO");
	}
	return 0;
}


博客保留所有权利,谢绝学步园、码迷等不在文首明显处显著标明转载来源的任何个人或组织进行转载!其他文明转载授权且欢迎!
原文地址:https://www.cnblogs.com/winlere/p/15112539.html