UOJ Logo RainAir的博客

博客

2019 正睿垫底总结

2019-08-14 19:33:25 By RainAir

把在 AB 班垫底总结没写的东西一块写了吧。。。

从 AB 班垫底之后来到了 C 班,本以为自己能涨一点点 rating,然后就: QQ20190814-192226.png

还是感谢蔡老板和老师们对菜鸡我辛勤的教导,我在正睿收获了很多(比如学会了 SAM 的读法),也深深认识到了自己的弱小。

本来之前还是想在 Day9 写一发正解的结果由于没打暴力直接 0 了,让我也知道了在打远高于我能力水平的比赛时上场应该优先打暴力。(不过什么时候我的水平能够达到 AB 班平均水平啊 QAQ)

还认识了好多高水平选手,比如周队,高爸,李队(虽然这些好像早就认识了),许队,徐队。。。真正认识到了我前面有人比我强,后面有人比我强,我在中间垫底的恐怖。

今年打完 NOIP 后估计就退役了,祝大家前程似锦!(我语文好差啊)20181230194916833.png20181230194731601.png20181230193958416.png20190103084314258.png

对比: 去年的 AB 班成绩:链接

今年的 AB 班成绩:

比赛名称 得分 排名
zr2019暑期高端峰会AB组day1 10 80
zr2019暑期高端峰会AB组day2 20 72
zr2019暑期高端峰会AB组day3 30 63
zr2019暑期高端峰会AB组day4 10 89
zr2019暑期高端峰会AB组day5 20 96
zr2019暑期高端峰会AB组day6 50 99
zr2019暑期高端峰会AB组day7 20 89
zr2019暑期高端峰会AB组day8 30 92
zr2019暑期高端峰会AB组day9 20 95

正睿OI联赛停课训练day11翻车记

2018-10-29 12:52:17 By RainAir

UPD: 哥哥们怎么都给差评啊QAQ @siyuan 说他想说这句话:

Siyuan 要 AK IOI!!!

本来以为自己是300分的...结果 $\to$ T1 不判 $l==r$ $ 70 $ 分 + T2 题目玄学取模 $ 30 $ 分 + T3 错用大根堆 $ 0 $ .

最后还掉了分...

告诉我们千万不要再 自认为AK 后去做一些别的事情还有被别人瞎膜最后被奶死。

大体总结:基本全是结论题,全是坑的较为简单的(相比泡泡糖)的模拟赛 $qwq$

线段树什么的最讨厌了

发现一个长度为 $len$ 区间 $[l,r]$ 的父亲只有四种情况:$[l,r+len],[l-len,r],[l,r+len-1],[l-len-1,r]$

大力dfs即可

注意到当 $l == r$ 的时候这样做可能被艹,直接特判输出 $l$ 或 $-1$. 代码:

#include <algorithm>
#include <iostream>
#include <cstring>
#include <climits>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>

#define Re register
#define LL long long
#define U unsigned
#define FOR(i,a,b) for(Re int i = a;i <= b;++i)
#define ROF(i,a,b) for(Re int i = a;i >= b;--i)
#define CLR(i,a) memset(i,a,sizeof(i))
#define BR printf("--------------------\n")
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl
#define int long long
int T;
LL L,R,lim,ans;

void dfs(LL l,LL r){
    if(r > lim || r > ans) return;
    if(!l) {ans=r;return;}
    int len = r-l+1;
    if(len+r <= lim && l >= 2*len) dfs(l,r+len);
    if(l-len >= 0) dfs(l-len,r);
    if(r+len-1 <= lim && l >= 2*len-1) dfs(l,r+len-1);
    if(!(l-len-1) || l-len-1 >= 2*len+1) dfs(l-len-1,r);
}

inline void Solve(){
    scanf("%lld%lld%lld",&L,&R,&lim);
    ans = LLONG_MAX;
    if(L == R) {printf("%lld\n",L <= lim ? L : -1);return;}
    dfs(L,R);
    if(ans == LLONG_MAX) puts("-1");
    else printf("%lld\n",ans);
}

signed main(){
    scanf("%lld",&T);
    while(T--) Solve();
    return 0;
}

已经没有什么好害怕的了

考虑到合法的括号序列 $[l,r]$ 会对这个区间的点的贡献增加 $1$

差分一下直接搞就可以了。

注意到该题的取模十分毒瘤!加起来是不需要取模的。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <climits>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>

#define Re register
#define LL long long
#define U unsigned
#define FOR(i,a,b) for(Re int i = a;i <= b;++i)
#define ROF(i,a,b) for(Re int i = a;i >= b;--i)
#define CLR(i,a) memset(i,a,sizeof(i))
#define BR printf("--------------------\n")
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl
#define int long long // important!!!
const int MAXN = 1000000 + 5;
const int ha = 1000000000+7;
int T,N;
char str[MAXN];
int st[MAXN],tp;
int l[MAXN],r[MAXN];
int rr[MAXN],ll[MAXN],f[MAXN];
LL ans;

inline void Solve(){
    ans = 0ll;
    scanf("%s",str + 1);
    N = strlen(str + 1);
    tp=0;CLR(l,0);CLR(r,0);CLR(ll,0);CLR(rr,0);CLR(f,0);
    FOR(i,1,N){
        if(str[i] == '(') st[++tp] = i;
        else if(tp){
            r[st[tp]] = i+1;
            l[i+1] = st[tp--];
        }
    }
    ROF(i,N+1,1) rr[l[i]] += ++rr[i];
    FOR(i,1,N+1) ll[r[i]] += --ll[i];
    FOR(i,1,N) f[i] = f[i-1] + rr[i] + ll[i];
    FOR(i,1,N) ans = (ans + i*f[i]%ha);
    printf("%lld\n",ans);
}

signed main(){
    scanf("%lld",&T);
    while(T--) Solve();
    return 0;
}

我才不是萝莉控呢

由于只能向左走,考虑动态规划。

设 $f[i][j]$ 表示走到点 $(i,j)$ 的最小花费,转移有 $f[i][j] = min(f[i-1][j+1],f[i][(j+1)/2 + \sum_{k=i+1}^n a[k])$

注意到该转移方程十分像 Huffman 树的动态规划做法的转移方程: 设 $g[i][j]$ 表示已经放置了 $i$ 个点,还需要放置 $j$ 个点的最小代价,转移有 $f[i][j] = min(f[i+1][j-1],f[i][j*2] + \sum_{k=i+1}^n val[k])$,只是过程倒过来了而已。

直接用优先队列维护一下求出序列 $a$ 的 Huffman 树的权值即可。注意 priority_queue<int> 默认是大根堆!!!不要像我这样被坑死了!!!

#include <algorithm>
#include <iostream>
#include <cstring>
#include <climits>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>

#define Re register
#define LL long long
#define U unsigned
#define FOR(i,a,b) for(Re int i = a;i <= b;++i)
#define ROF(i,a,b) for(Re int i = a;i >= b;--i)
#define CLR(i,a) memset(i,a,sizeof(i))
#define BR printf("--------------------\n")
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl
#define int long long //important
const int MAXN = 100000 + 5;
const int CANSIZE = 1000 + 5;

int N,x;
int a[MAXN],b[MAXN];
int f[CANSIZE][CANSIZE];
std::priority_queue<int,std::vector<int>,std::greater<int> > q;

inline void Solve(){
    scanf("%lld",&N);
    while(!q.empty()) q.pop();
    FOR(i,1,N) scanf("%lld",&x),q.push(x);
    int ans=0;
    FOR(i,1,N-1){
        int cnt=0;cnt += q.top();q.pop();
        cnt += q.top();q.pop();q.push(cnt);
        ans += cnt;
    }
    printf("%lld\n",ans);
}

signed main(){
    int T;scanf("%lld",&T);
    while(T--) Solve();
    return 0;
}

刷题惨案

2018-08-06 16:17:39 By RainAir
RainAir Avatar