http://codeforces.com/contest/1180(比赛链接)
莫名其妙的一场比赛
手速真的贼慢(前四真签到
两个小时就签签到。。真的扣脚
e题目都没看懂,剩下几分钟。。
A Alex and a Rhombus
数数找规律,每一圈多一个四的倍数

B 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)

D 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;
}
E 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.
本文解析了CodeForces平台上的比赛题目,包括A题的数数找规律、B题的数组变化以求最大乘积、C题的双端队列操作、D题的路径构造问题及E题的值域线段树应用,提供了详细的解题思路和代码实现。
2855

被折叠的 条评论
为什么被折叠?



