试着做了一下以往的asia区域赛 和想象的不大一样...
I 求平方和 签到题出的就很没意思..
J 怎么搞都行的简单组合数学
K 模拟 题目有点长但按照题意认真写就好
A 无语..最开始排序加后处理一下 wa 然后各种数学分析复杂度分析...一直wa..其实按a/b排序一下就好...
D 模拟的时候看了会 想到了枚举觉得不难 但心态爆炸在a就没做...讲道理是稳银冲金的题目 但比较简单简单...甚至不用枚举每个力度擦边对应的角度 强行暴力枚举角度就行...c语言级别..
C 其实有点难的题 据说现场赛数据很弱导致一些错误程序ac...然后官方题解标程也是错的..正解是离散化再bfs或者建图最短路 但难点是矩形边界可以走 但又不能穿过建筑的拐点 处理的时候有点麻烦…(L形状的8种特判..)
H 三维复杂计算几何 但据说比较模板...
E 全场ac不到10个 正解就是构造答案的几那句话 套上线段树就好 看了构造法后我都能写出来..
F 因式分解x^n-1 很数学的难题..这题的结论是发了论文的.. 找规律+多项式除法
剩下2题是真的是各方面都巨难...
B 巨复杂的图论+树形dp+概率
G ??? 比赛防ak 至今只有2份ac貌似还是一个代码...
模拟的3小时多 2小时都用来a题的数学分析了...
要是智力够的话..5题还是有希望的(很费解d为什么过的这么少) 剩下的题大多不是算法瓶颈 智力+代码能力+芝士水平的瓶颈…
主要是要快速切水题..切完基本稳铜 中等题并不一定算法很难 可能只是不太好想 然而水题卡住就没时间看中等题了
银牌及以下的计算几何通常是模板 应该学习一个 能切完水题的话可以1人推中等题2人写计算几何
补E的构造法+线段树代码:
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct { int l, r, n, ad, ma; }t[100005 << 2];
int z, c[100005 << 1];
void up(int i)
{
t[i].n = min(t[i << 1].n, t[i << 1 | 1].n);
}
void down(int i)
{
int x = t[i].ad;
t[i << 1].ad += x, t[i << 1].n += x;
t[i << 1 | 1].ad += x, t[i << 1 | 1].n += x;
t[i].ad = 0;
}
void build(int l, int r, int i)
{
t[i].l = l, t[i].r = r, t[i].ad = t[i].n = 0;
int mid = (l + r) >> 1;
if (l == r)
{
scanf("%d", &t[i].n), t[i].ma = z++;
return;
}
build(l, mid, i << 1), build(mid + 1, r, i << 1 | 1);
up(i);
}
void update(int l, int r, int ad, int i)
{
if (r < l) return;
if (l <= t[i].l&&r >= t[i].r)
{
t[i].ad += ad, t[i].n += ad;
return;
}
if (t[i].ad&&t[i].l != t[i].r) down(i);
int mid = (t[i].l + t[i].r) >> 1;
if (r <= mid) update(l, r, ad, i << 1);
else if (l > mid) update(l, r, ad, i << 1 | 1);
else
update(l, mid, ad, i << 1), update(mid + 1, r, ad, i << 1 | 1);
up(i);
}
int sea(int i, int n)
{
if (t[i].l == t[i].r) return t[i].ma;
down(i);
if (t[i << 1].n == n) return sea(i << 1, n);
return sea(i << 1 | 1, n);
up(i);
}
int main()
{
int n, k, f;
while (scanf("%d", &n) && n)
{
queue<int>a, b;
z = 1, f = 0;
build(1, n, 1);
while (a.size() + b.size() != n << 1)
{
if (t[1].n < 0) { f = 1; break; }
k = sea(1, t[1].n);
if (t[1].n == 0)
{
a.push(k), b.push(-k);
update(k, k, 1 << 28, 1);
if (k >= 1) update(1, k - 1, -1, 1);
}
else if (t[1].n > 0) {
if (b.empty()) { f = 2; break; }
if (1 - b.front() <= n)
update(-b.front() + 1, n, -1, 1);
a.push(b.front()), b.pop();
}
}
if (f) { puts("Impossible"); continue; }
z = 0;
while (!a.empty())
c[z++] = a.front(), a.pop();
while (!b.empty())
c[z++] = b.front(), b.pop();
while (z-- > 0)
printf("%d ", c[z]);
puts("");
}
}