【Codeforces】Round 569(div 2)

http://codeforces.com/contest/1180(比赛链接)

莫名其妙的一场比赛

手速真的贼慢(前四真签到

两个小时就签签到。。真的扣脚

e题目都没看懂,剩下几分钟。。

Alex and a Rhombus

数数找规律,每一圈多一个四的倍数

Nick and Array

 给一个数组ai可以变成ai=-ai-1,求使得乘积最大的数列

[贪心]我们发现正数变负数会使绝对值变大,0->-1

然后考虑n的奇偶性,偶数表示结果为正

如果n为奇数,将绝对值最大的变正影响最小,eg-2->1,-33->32,显然变-33影响小

再考虑一下特殊情况,如果全部为-1,当然是在n为奇数情况下,-1和0互换,之前改变绝对值最大的方式仍然成立,结果为零,不需要特判

 C Valeriy and Deque

给一个队列,每次取前两个,大的放队首,小的放队尾

问每次操作后前两个是啥(按出队顺序输出)

脑洞,我们发现一个有趣的事,当队首最大时,就不会变了,后面实际是一个循环队列

所以复杂度从O(m)降到O(n)

 

Tolik and His Uncle

从(1,1)到(n,m)n*m个格子都要经过,每次移动的改变(dx,dy)不能相同

构造题

我写的比较丑,先构造再求答案,然后因为无法存下1e6*1e6数据,虽然n*m<=1e6,我用了个map动态存表。。

// <D.cpp> - 08/04/19 20:00:18
// This file is made by YJinpeng
// Copyright (C) 2018 Whu University, Inc.
// Life is always full of passion

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <map>
#define MOD 1000000007
#define INF 1e9
using namespace std;
typedef long long LL;
const int MAXN=1000010;
inline int gi() {
	register int w=0,q=0;register char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')q=1,ch=getchar();
	while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
	return q?-w:w;
}
//struct node{int x,y;};
map<pair<int,int>,int>a;
int b[MAXN],c[MAXN];
int main()
{
	freopen("D.in","r",stdin);
	freopen("D.out","w",stdout);
	int n=gi(),m=gi(),nn=n>>1,nn1=(n+1)>>1,mm=m>>1,mm1=(m+1)>>1,nm=n*m,k1=1,k2=2;
	for(int j=1;j<=mm;j++)
		for(int i=1;i<=n;i++)
			a[make_pair(i,j)]=k1,k1+=2;
	for(int j=m;j>mm1;j--)
		for(int i=n;i>=1;i--)
			a[make_pair(i,j)]=k2,k2+=2;
	if(m%2==1){
		for(int i=1;i<=nn;i++)a[make_pair(i,mm+1)]=k1,k1+=2;
		for(int i=n;i>nn1;i--)a[make_pair(i,mm+1)]=k2,k2+=2;
		if(n%2==1)a[make_pair(nn+1,mm+1)]=k1;
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)b[a[make_pair(i,j)]]=i,c[a[make_pair(i,j)]]=j;
	for(int i=1;i<=nm;i++)printf("%d %d\n",b[i],c[i]);
	return 0;
}

Serge and Dining Room

ai 表示食物的价格

bi 表示每个人的最大购买价格

每个人顺序购买,买可以买的最贵的食物,如果没有购买,那么放弃购买

问每个人买了之后剩下最大价格的食物

然后每次询问都可以改变食物和人的购买价格

首先我们发现跟人买的顺序没关

构建值域线段树,t[a[i]]=1,t[b[i]]=-1

我们是不是找到最后那个食物就行,满足后缀和>0的最大坐标

// <E.cpp> - 08/04/19 20:00:18
// This file is made by YJinpeng
// Copyright (C) 2018 Whu University, Inc.
// Life is always full of passion

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#define MOD 100000007
#define INF 1e9
using namespace std;
typedef long long LL;
const int MAXN=1000010;
inline int gi() {
	register int w=0,q=0;register char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')q=1,ch=getchar();
	while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
	return q?-w:w;
}
int sm[MAXN<<2],mx[MAXN<<2],a[MAXN],b[MAXN];
void update(int k,int l,int r,int pos,int o){
	if(l==r){
		sm[k]+=o;mx[k]=sm[k];return;
	}
	int mid=(l+r)>>1;
	if(pos<=mid)update(k<<1,l,mid,pos,o);
	else update(k<<1|1,mid+1,r,pos,o);
	mx[k]=max(mx[k<<1]+sm[k<<1|1],mx[k<<1|1]);
	sm[k]=sm[k<<1]+sm[k<<1|1];
}
int query(int k,int l,int r,int o){
	if(l==r)return l;
	int mid=(l+r)>>1;
	if(o+mx[k<<1|1]>0)return query(k<<1|1,mid+1,r,o);
	else return query(k<<1,l,mid,o+sm[k<<1|1]);
}
int main()
{
	freopen("E.in","r",stdin);
	freopen("E.out","w",stdout);
	int n=gi(),m=gi();
	for(int i=1;i<=n;i++)update(1,1,MAXN,a[i]=gi(),1);
	for(int i=1;i<=m;i++)update(1,1,MAXN,b[i]=gi(),-1);
	int q=gi();
	while(q--){
		int sb=gi(),pos=gi(),val=gi();
		if(sb==1)update(1,1,MAXN,a[pos],-1),update(1,1,MAXN,a[pos]=val,1);
		else update(1,1,MAXN,b[pos],1),update(1,1,MAXN,b[pos]=val,-1);
		if(mx[1]<=0)printf("-1\n");
		else printf("%d\n",query(1,1,MAXN,0));
	}
	return 0;
}

 

This passage is made by ShinaCloud.

posted @ 2019-08-06 16:36  ShinaCloud  阅读(120)  评论(0)    收藏  举报