20210815 noip40
考场
开题发现都不可做
T1 先猜了个结论:答案的开始位置一定是某种颜色最后一次出现的位置,感觉很对(这样这种颜色一定有贡献),枚举 \(m\) 个这样的位置即可。
T2 给的距离好奇怪啊,但感觉比较可做
T3 部分分很好做,对正解毫无思路
顺序开题。
T1 题目没给 \(m\) 的范围。。。保险起见写了个离散化+暴力
T2 发现在同一条 \(y=x+b,y=-x+y\) 线上的点直接距离为 \(0\),那么可以以 \(b\) 为中转,把 \(n\) 个点先合并起来,考虑算最小距离,模样例发现取每个联通块最大的 \(b\),排序后相邻两个差的最小值就是答案,于是 \(O(n\log n)\) 做完了。拍了一下发现不对,在纸上画了许多图,仔细思考一波发现假了,但可以改成 \(O(n^2\log n)\) 的,好歹有 70pts,拍上后盯着图想到 9.40,还是不会(有一说一,期间有想到曼哈顿转切比雪夫,但下意识的否了),写 T3 去了
T3 突然发现 sub3 可能 \(T\) 很大,那就死了。。。写完前两个 sub 拍上了
看一眼 T2,WA 了???此时已经接近 10.10 了,脑子十分混乱且慌的一批,赶紧看了一遍代码,没啥问题啊。重拍了一下,发现正确率大于 \(99\%\),那应该还有戏,拼上暴力交了。
最后开始颓废 tetris
调试的时候试了下 cerr
,感觉非常好用
res
rk16 0+70+35
T1 结论伪了
T3 没模全,挂了 sub2,但暴力过了 sub4
rk1 张泽阳 100+100+35
rk4 ys 45+70+20
rk4 zjj 0+100+35
rk16 ycx 45+45+15
总结
考得太烂太烂了,几乎犯了以前犯过的所有大错
T1 猜结论(事后看显然是错的),还没有对拍(省选 D2T1)
T2 刚了近 2h,草稿纸上都画出了与坐标轴夹 \(\frac\pi4\) 的线,还是没想到曼哈顿转切比雪夫(国赛 D1T1)
T3 的 sub3 在叉了原来的做法后就没再想,但其实不难(国赛 D2T2)
自认 DS 比较强,但事实上能做出来的还是那些 sb 题,对于有一定思维含量/需要魔改的还是不会。这次 T2 看到式子没能立刻想到曼哈顿转切比雪夫,而当时学的时候还写过博客,说明学东西还是太浅了,大都只背了板子/记了结论,一旦考到涉及本质的东西就死了。
但事实上有区分度的还是这类题,板子谁都会,要想进队就得做出来难题,以后学东西的时候多注重理解,一遍学不会就多看几遍,不要学过就当学会。对于每个知识,遵循发明原因(为啥要用)->原理(为什么这么做)->实现(怎么写)->扩展(与其他知识结合)的流程,这样才能融会贯通,真正吃透它。复习 noip 的时候严格按这个流程来。
做不出来题的原因又找到一点:无效思考时间太多。今天 T2 在 9.00-9.40 中几乎没有任何进展,看似想了很久但想到的东西很少。DP 学的差也有这方面的原因,思考太混乱,一旦第一感觉错了就很难再想出来题。
以后想题时不要局限在一种思路,沉迷打补丁没有前途(尤其是 DS),及时换思路/推性质,对于每个性质想它能带来什么(题目中奇怪的地方同理)。每个思路也不要乱想,一步一步地想清楚它为什么对/不对,需要维护什么东西,复杂度瓶颈在哪里,有没有优化空间。
还有就是犯过的错再犯,虽然每次都写总结,但是没能拿出有效的措施,这点是致命的,这几天好好想想,暑假一定要解决。
考试的时候不要贪正解。这件事很久以前教练就说过,但一直没咋注意,能做出来题时无所谓,但遇上这几天比较难的时候就要拼部分分(今天不挂分也能 rk3),部分分也一定要拍。
以后每次考试前看看挂分指北。加个惩罚性措施:以 5.45 为线,挂一分早起 1min
最后一点,交了代码不要打 tetris,没事干就一遍一遍地读代码,或者估一下分,想想考场上的 3h 是怎么分配的,都干了什么,有没有可以改进的地方。
sol
叕没时间写了。。。
T1
const int N = 1e6+5;
int n,m,c[N];
LL d[N];
int lst[N][2];
LL ans;
#define ls (u<<1)
#define rs (u<<1|1)
struct Node { int l,r; LL mx,add; } t[N*4];
void up(int u) { t[u].mx = max(t[ls].mx,t[rs].mx); }
void down(int u,LL x) { t[u].mx += x, t[u].add += x; }
void down(int u) { down(ls,t[u].add), down(rs,t[u].add), t[u].add = 0; }
void build(int u,int l,int r) {
t[u].l = l, t[u].r = r;
if( l == r ) return;
int mid = l+r>>1;
build(ls,l,mid), build(rs,mid+1,r);
}
void modify(int u,int l,int r,LL x) {
if( l <= t[u].l && t[u].r <= r ) return down(u,x), void();
down(u);
if( l <= t[ls].r ) modify(ls,l,r,x);
if( t[rs].l <= r ) modify(rs,l,r,x);
up(u);
}
#undef ls
#undef rs
signed main() {
read(n,m);
For(i,1,n) read(c[i]);
For(i,1,m) read(d[i]);
build(1,1,n);
For(i,1,n) {
if( lst[c[i]][1] ) modify(1,lst[c[i]][0]+1,lst[c[i]][1],-d[c[i]]);
modify(1,lst[c[i]][1]+1,i,d[c[i]]);
lst[c[i]][0] = lst[c[i]][1], lst[c[i]][1] = i;
ckmax(ans,t[1].mx);
}
write(ans);
return iocl();
}
T2
const int N = 1e5+5, inf = 0x3f3f3f3f;
int n;
struct Node { int x,y,id; } p[N];
int mndis=inf,m,fa[N],siz[N];
LL ans;
PII e[N*2];
bool cmpx(const Node &x,const Node &y) { return x.x<y.x; }
bool cmpy(const Node &x,const Node &y) { return x.y<y.y; }
int find(int x) { return fa[x]==x ? x : fa[x]=find(fa[x]); }
void merge(int x,int y) {
if( (x=find(x)) == (y=find(y)) ) return;
fa[x] = y, siz[y] += siz[x];
}
void link(int x,int y) {
x = find(x), y = find(y);
if( x > y ) swap(x,y);
e[++m] = MP(x,y);
}
signed main() {
read(n);
For(i,1,n) {
int x,y; read(x,y);
p[i] = Node{x+y,x-y,i};
fa[i] = i, siz[i] = 1;
}
sort(p+1,p+n+1,cmpx);
for(int i = 1, j; j = i+1, i <= n; i = j) {
while( j <= n && p[i].x == p[j].x ) merge(p[i].id,p[j].id), ++j;
if( j > n ) break;
ckmin(mndis,p[j].x-p[i].x);
}
sort(p+1,p+n+1,cmpy);
for(int i = 1, j; j = i+1, i <= n; i = j) {
while( j <= n && p[i].y == p[j].y ) merge(p[i].id,p[j].id), ++j;
if( j > n ) break;
ckmin(mndis,p[j].y-p[i].y);
}
sort(p+1,p+n+1,cmpx);
for(int i = 1, j; j = i+1, i <= n; i = j) {
while( j <= n && p[i].x == p[j].x ) ++j;
if( j > n ) break;
if( p[j].x-p[i].x == mndis ) link(p[i].id,p[j].id);
}
sort(p+1,p+n+1,cmpy);
for(int i = 1, j; j = i+1, i <= n; i = j) {
while( j <= n && p[i].y == p[j].y ) ++j;
if( j > n ) break;
if( p[j].y-p[i].y == mndis ) link(p[i].id,p[j].id);
}
sort(e+1,e+m+1), m = unique(e+1,e+m+1)-e-1;
For(i,1,m) ans += (LL)siz[e[i].fi] * siz[e[i].se];
if( mndis == inf ) write(-1);
else write(mndis), write(ans);
return iocl();
}
T3
const int N = 1e7+5, mod = 998244353;
int m;
char s[N];
int n,n1,lst,pre;
LL ans2,base=1,res[N];
char ans1[N];
deque<int> dq;
signed main() {
scanf("%d%s",&m,s+1); n = strlen(s+1);
For(i,1,n) {
ans1[i] = '0';
if( s[i] == '0' ) res[0] += n1;
else ++n1;
}
For(i,1,m) dq.pb(i);
For(i,1,n) if( s[i] == '1' ) {
++pre, dq.push_front(1-pre);
while( !dq.empty() && dq.back()+pre > m ) dq.pop_back();
For(j,1,i-lst-1) {
if( dq.empty() ) break;
int k = dq.front()+pre; dq.pop_front();
++res[k], --res[min(k+n1-pre+1,m+1)];
}
ans1[i-(m-dq.size())] = '1';
lst = i;
}
For(i,2,m) res[i] = (res[i-1] + res[i]) %mod;
ans2 = (res[0] %= mod);
For(i,1,m) {
res[i] = (res[i-1] + res[i]) %mod;
base = base * 233 %mod, ans2 ^= res[i] * base %mod;
}
printf("%s\n%lld",ans1+1,ans2);
return 0;
}