Codeforces Round #707 Editorial Div2 题解

CF1501 Div2 题解

CF1501A

这道题其实是一道英语阅读题,然后样例解释又不清晰,所以我看了好久,首先它告诉了你每个站点的预期到达时间 \(a_i\) ,以及每个站点的预期出发时间 \(b_i\)

那么对每个站点来说,从上一个站点的预期出发时间 \(b_{i-1}\) 到当前站点的预期到达时间 \(a_{i}\) ,那么中间差的时间就是你从上一个站点到达这个站点的时间,计算出 \(go_i\) \(=\) \(a_i - b_{i-1}\) 就计算出第 \(i-1\) 个站点到达第 \(i\) 个站点的时间。

然后考虑限制:

  • 你需要在预期出发时间后出发
  • 你在一个站点至少要待 \(\lceil \cfrac{b_i-a_i}{2} \rceil\) 的时间

那么对于限制 \(2\) ,首先我们就加上这么多的时间,然后如果加上这么多的时间后,我们当前时间仍然小于预期时间,那就将时间更新为预期时间,然后就做完了。

#include<bits/stdc++.h>
#define int long long
using namespace std;
template<typename T> inline void read(T &x){
	T f=1;x=0;
	char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	x*=f;
}
const int N = 3000;
int T,n;
struct node{
	int x,y;
}f[N];
int t[N],go[N];
signed main(){
	read(T);
	while(T--){
		memset(f,0,sizeof(f));
		memset(t,0,sizeof(t));
		memset(go,0,sizeof(go));
	    read(n);
	   	for(int i=1;i<=n;i++){
	   		read(f[i].x),read(f[i].y);
	   		go[i]=f[i].x-f[i-1].y;
		}
		
		for(int i=1;i<=n;i++){
		read(t[i]);
		go[i]+=t[i];
		}
		int now=0;
		
		for(int i=1;i<=n;i++){
			now+=go[i];
	//		now+=t[i];
			if(i==n){
				printf("%lld\n",now);
				break;
			}
			int lt=ceil((double)(f[i].y-f[i].x) /2.0);
			now+=lt;
			if(now<f[i].y){
				now=f[i].y;
			}
			//now+=t[i];
		}
		
	}
    return 0;
}

CF1501B

这道题的题意就贼清晰了,然后就很简单了。
发现如果 \(a_i = 0\) 时,那么你就只用正常的叠加一层没被涂的。
否则,你就要叠一层,并且往下进行染色。
暴力进行染色肯定是会超时的,因为 \(1\) 个点有可能被染色多次,所以我采用了一种方式,那就是用树状数组来进行修改。
对要染色的区间的值都加上 \(1\) ,最后进行单点查询,如果值不为 \(0\) ,那就输出 \(1\) ,否则输出 \(0\).

#include<bits/stdc++.h>
#define int long long
using namespace std;
template<typename T> inline void read(T &x){
	T f=1;x=0;
	char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	x*=f;
}
const int N = 2e6;
int T,n,a[N],vis[N],tot=0,f[N],num;
vector<int>b;
vector<pair<int,int> > c;
int lowbit(int x){
	return x&(-x);
}
int c1[N],c2[N];
void update(int x,int k){
	int i=x;
	while(x<=n){
		c1[x]+=k;
		c2[x]+=i*k;
		x+=lowbit(x);
	}
}
int sum(int x){
	int ans=0,i=x;
	while(x>0){
		ans+=c1[x]*(i+1);
		ans-=c2[x];
		x-=lowbit(x);
	}
	return ans;
}
signed main(){
	read(T);
	while(T--){
		read(n);
		for(int i=1;i<=n;i++){
			read(a[i]);
		}
		for(int i=1;i<=n;i++){
			f[++num]=0;
			if(a[i]){
		//	f[++num]=1;
			int last=num-a[i]+1;
			if(last<=0) last=1;
			c.push_back( make_pair(last,num) );
			  
			}
		}
		for(int i=0;i<c.size();i++){
			int l=c[i].first;
			int r=c[i].second;
			update(l,1);
			update(r+1,-1);
		}
		for(int i=1;i<=num;i++){
			int x=sum(i);
			if(sum(i)-sum(i-1)==0){
				printf("0 ");
			}
			else printf("1 ");
		}
		puts("");
		for(int i=0;i<=num;i++) c1[i]=c2[i]=0;
		c.clear();
		num=0;
		
	}
    return 0;
}

CF1500A

这道题很显然就有一个暴力的平方想法,你可能认为会超时,但是实际是不会的。所以不要怕,直接暴力碾压就完事了吗,具体证明就不发了,因为我也不会,所以这篇就不交题解了。

#include<bits/stdc++.h>
using namespace std;
template<typename T> inline void read(T &x){
	T f=1;x=0;
	char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	x*=f;
}
const int N =6e6;
int n,a[N];
pair<int,int>vis[N];
int main(){
	read(n);
	for(int i=1;i<=n;i++) read(a[i]);
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++){
			int s=a[i]+a[j];
			if(!vis[s].first&&!vis[s].second){
				vis[s]=make_pair(i,j);
			}
			else{
				if(vis[s].first!=i&&vis[s].second!=i&&vis[s].second!=j&&vis[s].second!=i){
				
				puts("YES");
				printf("%d %d %d %d",vis[s].first,vis[s].second,i,j);
				return 0;
				}
			}
		}
	} 
	puts("NO");
	return 0;
}
posted @ 2021-03-15 18:04  edds  阅读(89)  评论(0编辑  收藏  举报