【Codeforces】Round 569(div 2)
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.