Codeforces Round #569 (Div. 1)
A:
首先模拟一段,等最大值到第一个的时候会开始循环。
#include
using namespace std;
const int N = 3e5+7;
int a[N];
int ansx[N], ansy[N];
using ll = long long;
int main() {
int n, q;
scanf("%d%d", &n, &q);
for(int i=0; i<n; ++i) scanf("%d", &a[i]);
int mx = 0;
for(int i=0; i<n; ++i) mx=max(mx, a[i]);
int p =0;
for(; p<n; ++p) if(a[p]==mx) break;
for(int i=0; i<p; ++i) {
ansx[i+1] = a[i];
ansy[i+1] = a[i+1];
if(a[i]>a[i+1]) {
a[i+n]=a[i+1];
a[i+1]=a[i];
} else {
a[i+n]=a[i];
}
}
while(q--) {
ll m;
scanf("%I64d", &m);
if(m<=p) printf("%d %d\n", ansx[m], ansy[m]);
else {
int id=(m-p-1)%(n-1);
printf("%d %d\n", a[p], a[p+id+1]);
}
}
return 0;
}
B:
考虑一维坐标轴完成相同任务,假设坐标轴长度为10,那么0,10,1,9,2,8,…这种方案显然满足条件。那么对于二维坐标轴其实每个点可以唯一地映射到一个一维坐标轴,那么映射过去就行了。
#include
using namespace std;
int main() {
int n, m;
scanf("%d%d", &n, &m);
int cur=0, diff=n*m-1;
for(int i=0; i<n*m; ++i) {
int x = cur/m+1;
int y = cur%m+1;
cur+=diff;
if(diff>0) {
diff=-diff+1;
} else {
diff=-diff-1;
}
printf("%d %d\n", x, y);
}
}
C:
对于所有pupil :在 [ 1 , b [ i ] ] [1, b[i]] [1,b[i]] 区间+1。
对于所有dished:在 [ 1 , a [ i ] ] [1,a[i]] [1,a[i]] 区间-1 。
可以看出,右边第一个小于0的点就是每次询问的答案。
对于每次修改,更新一下线段树就行。
#include
#define lson (rt<<1)
#define rson (rt<<1|1)
using namespace std;
const int V = 1e6+7;
const int N = 3e6+7;
int lz[V<<2], mn[V<<2];
void push_down(int rt) {
if(lz[rt]) {
lz[lson] += lz[rt];
lz[rson] += lz[rt];
mn[lson] += lz[rt];
mn[rson] += lz[rt];
lz[rt]=0;
}
}
void push_up(int rt) {
mn[rt] = min(mn[lson], mn[rson]);
}
void update(int rt, int l, int r, int ql, int qr, int val) {
if(ql<=l&&qr>=r) {
lz[rt] += val;
mn[rt] += val;
return;
}
push_down(rt);
int m = (l+r)/2;
if(ql<=m) update(lson, l, m, ql, qr, val);
if(qr>m) update(rson, m+1, r, ql, qr, val);
push_up(rt);
}
int query(int rt, int l, int r) {
if(l==r) return l;
push_down(rt);
int m = (l+r)/2;
int res;
if(mn[rson]<0) res = query(rson, m+1, r);
else res = query(lson, l, m);
push_up(rt);
return res;
}
int a[N], b[N];
int main() {
int n, m, q;
scanf("%d%d", &n, &m);
int vn = 1000000;
for(int i=1; i<=n; ++i) {
scanf("%d", &a[i]);
update(1, 1, vn, 1, a[i], -1);
}
for(int i=1; i<=m; ++i) {
scanf("%d", &b[i]);
update(1, 1, vn, 1, b[i], 1);
}
scanf("%d", &q);
while(q--) {
int op, i, x;
scanf("%d%d%d", &op, &i, &x);
if(op==1) {
update(1, 1, vn, 1, a[i], 1);
a[i] = x;
update(1, 1, vn, 1, a[i], -1);
} else {
update(1, 1, vn, 1, b[i], -1);
b[i] = x;
update(1, 1, vn, 1, b[i], 1);
}
int ans;
if(mn[1]>=0) ans = -1;
else ans = query(1, 1, vn);
printf("%d\n", ans);
}
return 0;
}
D:
好像是斜率优化DP,待补。。。