Codeforces Round #569 (Div. 2)

A. Alex and a Rhombus

规律思维

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
#define FI first
#define S second
const int M = 1e5 + 10;
const ll INF64=8000000000000000000LL;
const int INF=0x3f3f3f3f;
const ll MOD=ll(1e9+7);
const ld PI=acos(-1);
const ld eps=1e-9;
using namespace std;
int a[110];
int main()
{
    ios::sync_with_stdio(false);
    
	cin.tie(0);
    int n;
	cin>>n;
	a[1]=1;
    for(int i=2;i<=100;i++)
    a[i]=a[i-1]+(i-1)*4;
	cout<<a[n]<<endl;
   	return 0;
}


B

Nick and Array

 

发现:x==-(-(x+1))+1.所以每个数有2种取值,贪心即可。

优先让所有数乘积为正。然后优先让数绝对值尽可能大

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
#define F first
#define S second
const int M = 1e5 + 10;
const ll INF64=8000000000000000000LL;
const int INF=0x3f3f3f3f;
const ll MOD=ll(1e9+7);
const ld PI=acos(-1);
const ld eps=1e-9;
using namespace std;
int a[M];
int z[M];
int f[M];
int pr[M];
pii p[M];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
   	int n;
   	int num=0;
   	cin>>n;
   	for(int i=1;i<=n;i++)
   	{
   		cin>>a[i];
   		
   		if(a[i]>=0)
   		z[i]=a[i],f[i]=a[i]+1;
   		else f[i]=-a[i],z[i]=-a[i]-1;
   		p[i].F=max(z[i],f[i]),p[i].S=i;
		if(p[i].F==f[i])
   		num++;
	}
//	cout<<num<<"   "<<endl;
	if(num%2==0)
	{
		for(int i=1;i<n;i++)
		if(p[i].F==z[i])
		cout<<z[i]<<" ";
		else
		cout<<-f[i]<<" ";
		
		if(p[n].F==z[n])
		cout<<z[n]<<endl;
		else
		cout<<-f[n]<<endl;
		return 0;
	}
	sort(p+1,p+1+n);
	for(int i=n;i>=1;i--)
	{
		if(p[i].F==f[p[i].S])
		{
			p[i].F--;
		//	cout<<p[i].F<<" --"<<i<<endl;
			break;
		}
	}
	for(int i=1;i<=n;i++)
	pr[p[i].S]=p[i].F;
	for(int i=1;i<n;i++)
	if(pr[i]==z[i])
	cout<<z[i]<<" ";
	else
	cout<<-f[i]<<" ";
	
	if(pr[n]==z[n])
	cout<<z[n]<<endl;
	else
	cout<<-f[n]<<endl;
   	return 0;
}


C. Valeriy and Deque

先用双端队列模拟第一轮,记录。

然后发现后面数组顺序不会发生变化。

输出即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
#define F first
#define S second
const int M = 2e5 + 10;
const ll INF64=8000000000000000000LL;
const int INF=0x3f3f3f3f;
const ll MOD=ll(1e9+7);
const ld PI=acos(-1);
const ld eps=1e-9;
using namespace std;
int a[M];
ll p[M];
pii id[M];
deque<int> dq;
int pr[M];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n,q;
    cin>>n>>q;
    int ma=-INF;
    for(int i=1;i<=n;i++)
    cin>>a[i],ma=max(a[i],ma),dq.push_back(a[i]);
    for(int i=1;i<=q;i++)
    cin>>p[i];
    ll mod=n-1;
    ll time=0;
    while(dq.front()!=ma)
    {
    	int A=dq.front();
    	dq.pop_front();
    	int B=dq.front();
    	dq.pop_front();
    	dq.push_front(max(A,B));
    	dq.push_back(min(A,B));
    	time++;
    	id[time].F=A,id[time].S=B;
	}
	dq.pop_front();
	int cnt=0;
	while(!dq.empty())
	{
		pr[++cnt]=dq.front();
		dq.pop_front();
	}
	for(int i=1;i<=q;i++)
	{
		if(p[i]<=time)
		cout<<id[p[i]].F<<" "<<id[p[i]].S<<endl;
		else
		{
			ll now=(p[i]-time)%mod;
			if(now==0)now=mod;
			cout<<ma<<" "<<pr[now]<<endl;
		}
	}
   	return 0;
}
/*
2 6
1 2
1 2 3 4 5 6
*/

 

D. Tolik and His Uncle

构造题。

我们发现:每次跳斜对角,跳的横坐标和纵坐标之差一直不会重复。

所以我们直接按这个输出坐标就行。

可以现在纸上画画,找到规律再输出会方便很多,用cin会T!!!;

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
#define F first
#define S second
const int M = 1e6 + 10;
const ll INF64=8000000000000000000LL;
const int INF=0x3f3f3f3f;
const ll MOD=ll(1e9+7);
const ld PI=acos(-1);
const ld eps=1e-9;
using namespace std;
//map<int,int>mp[M<<1],mmp[M<<1];
int main()
{
   /* ios::sync_with_stdio(false);
    cin.tie(0);*/
    int n,m;
    cin>>n>>m;
    if(n==1)
    {
    	for(int i=1;i<=n*m;i++)
    	{
    		if(i&1)
    		printf("1 %d\n",(i+1)/2);
    		else
    		printf("1 %d\n",m-i/2+1);
		}
		return 0;
	}
    
	int x1=1,y1=1,x2=n,y2=m,flag1=1,flag2=1,tag1=0,tag2=0;
    for(int i=1;i<=n*m;i++)
    {
    //	cout<<i<<endl;
    	if(i&1)
    	{
    		printf("%d %d\n",x1,y1);
    		//cout<<x1<<" "<<y1<<endl;
    		if((x1==n||x1==1)&&tag1)
    		{
    			flag1^=1;
    			y1++;
    			tag1=0;
    			continue;
			}
    		if(flag1)x1++;
    		else x1--;
    		tag1=1;
		}
		else
		{
			printf("%d %d\n",x2,y2);
			//cout<<x2<<" "<<y2<<endl;
    		if((x2==n||x2==1)&&tag2)
    		{
    			flag2^=1;
    			y2--;
    			tag2=0;
    			continue;
			}
    		if(flag2)x2--;
    		else x2++;
    		tag2=1;
		}
	}
   	return 0;
}


E. Serge and Dining Room

每个人都会买自己能买的菜中最贵的菜,所以先后顺序并不影响结果。

问最后剩的菜最贵的是多少。如果不剩  输出-1.

因为每个人只能买一道,而且买自己所能买的最贵的菜。所以我们可以用区间覆盖表示一个人的购买力。

即:一个人有x元,那就在1--x区间-1,一道菜y元,就在1--y区间-1。处理所有菜和人后,如果最后整个区间有大于0的数,那就说明有剩的菜。输出最大的大于0的数,即最后剩的菜,没有则输出-1.

上述操作可以用权值线段树来做。区间更新+区间查询大于0且最大的数。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
#define F first
#define S second
const int M = 1e6 + 10;
const int N = 1e6+9;
const ll INF64=8000000000000000000LL;
const int INF=0x3f3f3f3f;
const ll MOD=ll(1e9+7);
const ld PI=acos(-1);
const ld eps=1e-9;
using namespace std;
int st[M<<2],lazy[M<<2],a[M],b[M];
void pushdown(int l,int r,int rt)
{
	if(lazy[rt]!=0)
	{
		lazy[rt<<1]+=lazy[rt];
		lazy[rt<<1|1]+=lazy[rt];
		st[rt<<1]+=lazy[rt];
		st[rt<<1|1]+=lazy[rt];
		lazy[rt]=0;
	}
}
void update(int l,int r,int rt,int x,int y,int d)
{
	//printf("%d %d-/-/-/----%d %d %d %d\n",x,y,l,r,rt,st[rt]);
	if(x<=l&&r<=y)
	{
		lazy[rt]+=d;
		st[rt]+=d;
		return ;
	}  
	pushdown(l,r,rt);
	//printf("%d %d--- %d   %d\n",l,r,st[rt<<1],st[rt<<1|1]);
	int mid=(l+r)>>1;
	if(x<=mid)	update(l,mid,rt<<1,x,y,d);
	if(y>mid)	update(mid+1,r,rt<<1|1,x,y,d);
	st[rt]=min(st[rt<<1],st[rt<<1|1]);
}
int query(int l,int r,int rt)
{
	if(l==r)
	{
		if(l==1&&st[rt]>=0)
			return -1;
		return l;
	}
	pushdown(l,r,rt);
	int mid=(l+r)>>1;
	//printf("%d %d--- %d   %d\n",l,r,st[rt<<1],st[rt<<1|1]);
	if(st[rt<<1|1]<0)return query(mid+1,r,rt<<1|1);
	return query(l,mid,rt<<1);
}/*
int Query(int l,int r,int rt,int x,int y)
{
	if(x<=l&&r<=y)
	{
		return st[rt];
	}
	pushdown(l,r,rt);
	int mid=(l+r)>>1;
	int A=INF,B=INF;
	if(x<=mid)A=Query(l,mid,rt<<1,x,y);
	if(y>mid)B=Query(mid+1,r,rt<<1|1,x,y);
	return min(A,B);
}*/
int main()
{
    /*ios::sync_with_stdio(false);
    cin.tie(0);*/
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
    	scanf("%d",&a[i]);
    	update(1,N,1,1,a[i],-1);
    //	printf("%d    -aaaaaaa-     %d\n",query(1,N,1),Query(1,N,1,1,N));
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&b[i]);
		update(1,N,1,1,b[i],1);
	//	printf("%d    -bbbbb-     %d\n",query(1,N,1),Query(1,N,1,1,N));
	}
//	printf("%d   -cc-   %d\n",query(1,N,1),Query(1,N,1,1,N));
	int q,c,x,y;
	scanf("%d",&q);
	for(int i=1;i<=q;i++)
	{
		scanf("%d%d%d",&c,&x,&y);
		if(c==1)
		{ 
		//	printf("%d--- %d\n",a[x],y);
			update(1,N,1,1,a[x],1);
			update(1,N,1,1,y,-1);
			a[x]=y;
		}
		else
		{
		//	printf("%d--- %d\n",b[x],y);
			update(1,N,1,1,b[x],-1);
			update(1,N,1,1,y,1);
			b[x]=y;
		}
		printf("%d\n",query(1,N,1));
	}
   	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值