2019/10/17 CSP模拟 总结

T1 补票 Ticket

没什么好说的,不讲了

T2 删数字 Number

很后悔的是其实考场上不仅想出了正解的方程,甚至连优化都想到了,却因为码力不足只打了\(O(n^2)\)暴力,甚至还因为细节挂成了\(40\ pts\)
以后还是应该多写一下码农题

规定一下,下面的\(j\)没有特殊说明,取值范围默认在\(1, i - 1\)
考虑什么情况是合法的,首先最后对答案有贡献的元素组成的序列一定是严格上升的,即\(a_i > a_j\)
然后考虑还有没有别的限制呢
放一个图

看到我们的对答案有贡献的序列和其对应的坐标的连边一定是一个越来越倾斜(并且逆时针旋转)的过程,思考一下为什么,发现如果不满足前面那个条件的话实际上是没法通过题目的变换方法得到最终对应的序列
举个例子

1 2 3 5 2
其中的3和5并不能同时对答案作出贡献

所以又有了一个限制条件\(i - a[i] > = j - a[j]\)

看一下两个条件\[a_i > a_j\] \[i - a[i] > = j - a[j]\]
发现是一个二维偏序
考虑一维一维的处理,先按第一个条件排一下序,然后在排序后的序列上处理后面那个条件,树状数组维护一下

#include<bits/stdc++.h>
#define N (100000 + 10)
#define lowbit(x) (x & (-x))
using namespace std;
inline int read() {
    int cnt = 0, f = 1; char c = getchar();
    while (!isdigit(c)) {if (c == '-') f = -f; c = getchar();}
    while (isdigit(c)) {cnt = (cnt << 3) + (cnt << 1) + (c ^ 48); c = getchar();}
    return cnt * f;
}
int n, tot, w, ans, gmax, BIT[N];
void modify(int x, int g) {
    for (; x <= gmax; x += lowbit(x)) BIT[x] = max(BIT[x], g);
}
int query(int x) {
    int ans = 0;
    for (; x; x -= lowbit(x)) ans = max(ans, BIT[x]);
    return ans;
}
struct node {
    int d, s;  //d: i - a[i].s, s: from input
}a[N];
bool cmp(node a, node b) {
    return a.d == b.d ? a.s < b.s : a.d < b.d;
}
int main() {
    n = read();
    for (register int i = 1; i <= n; ++i) {
        w = read();
        if (w > i) continue;
        a[++tot].s = w, a[tot].d = i - w;
        gmax = max(gmax, w);
    }
    sort (a + 1, a + tot + 1, cmp);
    for (register int i = 1; i <= tot; ++i) {
        int d = query(a[i].s - 1) + 1;
        modify(a[i].s, d);
        ans = max(ans, d);
    } printf("%d\n", ans);
    return 0;
}

T3 滑冰 Shortest

感觉题解很好理解,但就是想不到
先说一下算法流程
分别按\(x\)排一个序,\(y\)排一个序,然后相邻的连上边,跑最短路即可



说一下为什么是正确的
首先\(min(|x[i] - x[j]|, |y[i] - y[j]|)\)这个条件是完全不用考虑的,因为最短路本身就是找\(min\)的过程,就算两条边都连上也可以得到正确答案
考虑\(O(n^2)\)暴力,即每个点往其他所有点连边,然后这样显然跑不动
怎么优化呢
上面那个算法很巧妙的一点是,因为我们排过序了,所以两个点之间的连边一定已经是不可以分拆的最小单位了,并且用这些最小单位边一定可以组成其他的边,相当于去除了暴力连边中的重复信息,于是复杂度优化为\(O(nlog(n))\)

#include<bits/stdc++.h>
#define N (1001000 + 10)
using namespace std;
inline int read() {
    int cnt = 0, f = 1; char c = getchar();
    while (!isdigit(c)) {if (c == '-') f = -f; c = getchar();}
    while (isdigit(c)) {cnt = (cnt << 3) + (cnt << 1) + (c ^ 48); c = getchar();}
    return cnt * f;
}
int n, z;
struct node {
    int x, y;
    int pos;
}a[N];
bool cmp(node a, node b) {
    return a.x == b.x ? a.y < b.y : a.x < b.x;
}
bool cmp2(node a, node b) {
    return a.y == b.y ? a.x < b.x : a.y < b.y;
}
int first[N], nxt[N << 1], to[N << 1], w[N << 1], tot;
long long d[N];
bool vis[N];
void add(int x, int y, int z) {nxt[++tot] = first[x], first[x] = tot, to[tot] = y, w[tot] = z;}
priority_queue < pair<int, int> > q;
void dijkstra() {
    memset(d, 0x3f, sizeof d);
    memset(vis, 0, sizeof vis);
    d[1] = 0;
    q.push(make_pair(-d[1], 1));
    while (!q.empty()) {
        int x = q.top().second; q.pop();
        if (vis[x]) continue;
        vis[x] = 1;
        for (register int i = first[x]; i; i = nxt[i]) {
            int v = to[i], z = w[i];
            if (d[v] > d[x] + z) {
                d[v] = d[x] + z;
                q.push(make_pair(-d[v], v));
            }
        }
    }
}
int main() {
//  freopen("shortest.in", "r", stdin);
//  freopen("shortest.out", "w", stdout);
    n = read();
    for (register int i = 1; i <= n; ++i) a[i].x = read(), a[i].y = read(), a[i].pos = i;
    sort (a + 1, a + n + 1, cmp);
    for (register int i = 1; i < n; ++i) {
        int z = a[i + 1].x - a[i].x;
        add(a[i].pos, a[i + 1].pos, z), add(a[i + 1].pos, a[i].pos, z);
    }
    sort (a + 1, a + n + 1, cmp2);
    for (register int i = 1; i < n; ++i) {
        int z = a[i + 1].y - a[i].y;
//      cout<<z<<endl;
        add(a[i].pos, a[i + 1].pos, z), add(a[i + 1].pos, a[i].pos, z);
    }
    dijkstra();
    printf("%lld", d[n]);
    return 0;
}

原文地址:https://www.cnblogs.com/kma093/p/11693279.html

时间: 2024-10-03 23:15:25

2019/10/17 CSP模拟 总结的相关文章

2019.10.26 CSP%您赛第三场

\(CSP\)凉心模拟^_^ --题源\(lqx.lhc\)等各位蒟蒻 题目名称 比赛 传递消息 开关灯 源文件名 \(competition.cpp\) \(message.cpp\) \(light.cpp\) 输入文件名 \(competition.in\) \(message.in\) \(light.in\) 输出文件名 \(competition.out\) \(message.out\) \(light.out\) 测试点时限 \(1s\) \(1s\) \(2s\) 内存限制 \

2019.10.30 csp-s模拟测试94 反思总结

头一次做图巨的模拟题OWO 自从上一次听图巨讲课然后骗了小礼物以后一直对图巨印象挺好的233 T1: 对于XY取对数=Y*log(x) 对于Y!取对数=log(1*2*3*...*Y)=log1+log2+log3+...+logY 因为数字大小不超过1e5,直接累加最后比较就可以了 #include<iostream> #include<cstdio> #include<cmath> using namespace std; int t,x,y; double a,b

2019/10/3 CSP-S 模拟测

T1 Permut 题意: 求\(1 - n\)的排列中逆序对数量为\(k\)的排列的个数 SOL: 排除法我们知道一定不是\(O(n!)\)的算法 考虑\(dp\),现在已经有\(n-1\)的答案了,考虑新加入一个数产生多少新的逆序对 设\(dp[i][j]\)表示\(1 -i\)的排列有\(j\)个逆序对的数量,考虑新加入的数插在哪里会增加多少逆序对数量 有\[dp[i][j] = \sum\limits ^{min(i - 1, j)}_k dp[i - 1][j - k]\] 看起来有点

2019.10.21 csp-s模拟测试81 反思总结

T1: 把每一行状压,按行DP.设fi,j,k,i表示第几行,j是当前行的1覆盖状态,k是当前行选择按钮的状态.转移的时候枚举j和k,再枚举下一层的按钮选择情况l.如果l和j可以全覆盖当前层则转移合法,根据下一层选择l状态的代价进行转移.预处理一行每一种选法i可以覆盖到的状态di,各行选择按钮状态i对应的代价dpi,以及每一行的初始状态bi.转移时下一层的覆盖情况就是k|dl|bi+1.初始化第一层是所有选法i对应的代价,即f1,d[i]|b[1],i=dp1,i. 整个DP过程的复杂度是O(3

2019.10.22 csp-s模拟测试82 反思总结

算了 我在干什么orz T2: #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=1e5+10,p=1500007,mod=998244353; int n,len,cnt1=1,cnt2=1,lens; char s[2*N],c[2*N]; int tree1[2*N][27],tree2[2*N][27]; unsigned long lon

2019.10.26 csp-s模拟测试88 反思总结

今天的主人公是什么? 60.1K!!!! 先扔代码再更新防止我等会儿一上头不打算写完题解 T1: #include<iostream> #include<cstdio> #include<algorithm> using namespace std; const double inf=214748364; int n,k; double a[100010],f[21][100010]; int main() { scanf("%d%d",&n

2019/11/1 CSP模拟

写在前面的反思 该拿的部分分还是得拿完啊,因为懒+动作慢没有写最后一道题的菊花图和链的情况,其实这两个点并不难.. 虽然只有\(10pts\),但是已经足够往上爬一截了啊,额外的\(10pts\)在今天大众分\(210pts\)的背景下显得好重要 另外\(T2\)下来发现最后判断的地方假了,所幸好像它能跑得动的数据范围内都没出问题,但要卡还是很好卡,只是这次运气好没被卡而已,下次写的时候还是要注意,正式比赛不一定就不卡了 T1 \(sb\)题 对于\(b==1\),判断所有总数的\(gcd\)能

2019.10.1 qbxt模拟题

第一题 考虑树上\(DP\),f[i][j][0/1]表示以\(i\)为根的子树,入读为零点的个数为\(j\),点\(i\)的入度为\(0\)/不为\(0\)时的方案数 转移的时候考虑\(u\)的一个子树\(v\)的贡献,分类讨论边\((u,v)\)的两个方向的两个方案,具体的转移方程看代码 记录子树size,利用"刷表法",只进行有用的转移,复杂度\(O(n^2)\) #include<iostream> #include<cstring> #include&

2019.10.16&amp;17小结

话说也蛮久没写小结了,主要这两次考试失分严重,还是总结下吧. 10.16 T1 小奇挖矿2 100/0 [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿石交易市场,以便为飞船升级无限非概率引擎. [问题描述] 现在有m+1个星球,从左到右标号为0到m,小奇最初在0号星球. 有n处矿体,第i处矿体有ai单位原矿,在第bi个星球上. 由于飞船使用的是老式的跳跃引擎,每次它只能从第x号星球移动到第x+4号星球或x+7号星球.每到一个星球,小奇会采走该星球上所有的