暑假第二十六测

今天又考的奇差

题解:

第一题;

这么简单一道题我想了好久,智商实在是下线了;

#include<bits/stdc++.h>
using namespace std;

int main(){
    freopen("shortway.in","r",stdin);
    freopen("shortway.out","w",stdout);
    int n, k;
    scanf("%d%d", &n, &k);
    if((n - 1) % k == 0)printf("%d\n", (n - 1) / k * 2);
    if((n - 1) % k == 1)printf("%d\n", (n - 1) / k * 2 + 1);
    if((n - 1) % k >= 2)printf("%d\n", (n - 1) / k * 2 + 2);
}

第二题:我们发现e的长度很小,我们可以在上面做文章,其实每个位置对应的%strlen(e)都是一样的;我们用树状数组维护rt[pos][len][yu][id]表示1到POS每次跳len,当前位置%len = yu的id字符有多少个;对于一个字符串,查询就是rt[R][len][(L + i - 1) % len][a[i]],修改就把长度枚举一下;

这道题我开始想到每次跳len, 维护一个前缀和,但没有想到树状数组,暴力修改和我直接暴力复杂度差不多;如果想到余数这一维就好了

#include<bits/stdc++.h>
using namespace std;
const int M = 1e5 + 10;
char s[M], ch[M];
int rt[M][11][10][4], n, a[M], b[M];
inline int get(char x){
    switch(x){
        case ‘A‘:return 0;
        case ‘T‘:return 1;
        case ‘C‘:return 2;
        case ‘G‘:return 3;
    }
}
inline int lowbit(int x){return x & (-x);}
void add(int pos, int len, int yu, int id, int d){
    for(int x = pos; x <= n; x += lowbit(x)){
            rt[x][len][yu][id] += d;
    }
}
int query(int pos, int id, int k, int yu){
    int ret = 0;
    for(int x = pos; x; x -= lowbit(x)){
        ret += rt[x][k][yu][id];
    }
    return ret;
}

void init(){
    for(int i = 1; i <= n; i++)
        for(int k = 1; k <= 10; k++){
            add(i, k, i % k, a[i], +1);
    }
}
void add(int pos, int id, int d){
    for(int k = 1; k <= 10; k++)
        add(pos, k, pos % k, id, d);
}
int main(){
    freopen("evolution.in","r",stdin);
    freopen("evolution.out","w",stdout);
    scanf("%s", s);
    n = strlen(s);
    for(int i = 1; i <= n; i++)a[i] = get(s[i - 1]);
    init();
    int q, opt, l, r;
    scanf("%d", &q);
    while(q--){
        scanf("%d", &opt);
        if(opt == 1){
            scanf("%d%s", &l, ch);
            int t = get(ch[0]);
            add(l, a[l], -1);
            add(l, t, +1);
            a[l] = t;
        }
        else {
            scanf("%d%d%s", &l, &r, ch );
            int ans = 0, len = strlen(ch);

            for(int i = 1; i <= len; i++){
                b[i] = get(ch[i - 1]);
                ans += query(r, b[i], len, (l + i - 1) % len);
                ans -= query(l - 1, b[i], len, (l + i - 1) % len);
            }
            printf("%d\n", ans);
        }
    }
}

第三题:

线段树存树边,维护最大值更新非树遍,用非树边更新线段树上的限制;

#include<bits/stdc++.h>
using namespace std;
const int M = 2e5 + 10;
const int oo = 0x3f3f3f3f;
#define ex(i, u) for(int i = h[u]; i; i = G[i].nxt)
#define Ls nd->ls, lf, mid
#define Rs nd->rs, mid + 1, rg
int fa[M], ans[M], n, m, h[M], top[M], siz[M], son[M], dep[M], in[M];
int idc, tot, seq[M], line[M];
bool intree[M], fg;
struct edge{int u, v, w, id;}g[M];
struct Edge{int nxt, v, id;}G[M << 1];
void add(int u, int v, int i){
    G[++tot].v = v; G[tot].nxt = h[u]; h[u] = tot; G[tot].id = g[i].id;
}
bool cmp(edge a, edge b){
    return a.w < b.w;
}
bool cmp_id(edge a, edge b){
    return a.id < b.id;
}
int find(int x){
    if(x == fa[x])return x;
    return fa[x] = find(fa[x]);
}
void uni(int u, int v){
    fa[find(u)] = find(v);
}
struct Node;
void modify(int L, int R, int d, Node * nd, int lf, int rg);
struct Node{
    Node *ls, *rs;
    int mx, mi, tag;

    inline void down(int lf, int rg){
        if(tag != oo){
            int mid = (lf + rg) >> 1;
            modify(lf, mid, tag, ls, lf, mid);
            modify(mid + 1, rg, tag, rs, mid + 1, rg);
            tag = oo;
        }
    }

    inline void up(){
        mx = max(ls->mx, rs->mx);
    }
}pool[M << 2], *tail = pool, *root;
Node * build(int lf = 1, int rg = n){
    Node *nd = ++tail;
    if(lf == rg) {
        nd->mi = nd->tag = oo;
        nd->mx = g[line[seq[lf]]].w;
    }
    else {
        int mid = (lf + rg) >> 1;
        nd->ls = build(lf, mid);
        nd->rs = build(mid + 1, rg);
        nd->tag = nd->mi = oo;
        nd->up();
    }
    return nd;
}

int query(int L, int R, Node * nd = root, int lf = 1, int rg = n){
    if(L <= lf && rg <= R) return nd->mx;
    else {
        nd->down(lf, rg);
        int mid = (lf + rg) >> 1;
        int ans = 0;
        if(L <= mid)ans = max(ans, query(L, R, Ls));
        if(R > mid)ans = max(ans, query(L, R, Rs));
        return ans;
    }

}
void modify(int L, int R, int d, Node * nd = root, int lf = 1, int rg = n){
    if(L <= lf && rg <= R) {
        nd->tag = min(nd->tag, d);
        nd->mi = min(nd->mi, d);
        return ;
    }
    else {
        nd->down(lf, rg);
        int mid = (lf + rg) >> 1;
        if(L <= mid)modify(L, R, d, Ls);
        if(R > mid)modify(L, R, d, Rs);
        //nd->up();// ???
    }
}

void getdown(Node * nd = root, int lf = 1, int rg = n){
    if(lf == rg){
        ans[line[seq[lf]]] = nd->mi;
        return ;
    }
    nd->down(lf, rg);
    int mid = (lf + rg) >> 1;
    getdown(Ls);
    getdown(Rs);
}
void dfs(int u, int f){
    dep[u] = dep[f] + 1;
    siz[u] = 1;
    fa[u] = f;

    ex(i, u){
        int v = G[i].v;
        if(v == f)continue;
        dfs(v, u);
        line[v] = G[i].id;
        siz[u] += siz[v];
        if(siz[v] > siz[son[u]])son[u] = v;
    }
}
void dfs2(int u, int tp){
    in[u] = ++idc;
    seq[idc] = u;
    top[u] = tp;

    if(son[u])dfs2(son[u], tp);
    ex(i, u){
        int v = G[i].v;
        if(v == fa[u] || v == son[u])continue;
        dfs2(v, v);
    }
}
void Modify(int u, int v, int d){
    while(top[u] != top[v]){
        if(dep[top[u]] < dep[top[v]])swap(u, v);
        modify(in[top[u]], in[u], d);
        u = fa[top[u]];
    }
    if(dep[u] < dep[v])swap(u, v);
    if(in[u] != in[v])modify(in[v] + 1, in[u], d);
}
int Query(int u, int v){
    int ans = 0;
    while(top[u] != top[v]){
        if(dep[top[u]] < dep[top[v]])swap(u, v);
        ans = max(ans, query(in[top[u]], in[u]));
        //if(fg)printf("%d %d %d %d %d %d %d\n", u, v, dep[top[u]], dep[top[v]], in[top[u]], in[u], ans);
        u = fa[top[u]];
    }
    if(dep[u] < dep[v])swap(u, v);
    if(in[u] != in[v])ans = max(ans, query(in[v] + 1, in[u]));
    //if(fg)printf("%d %d %d\n", u, v, ans);
    return ans;
}

int main(){
    freopen("mst.in","r",stdin);
    freopen("mst.out","w",stdout);
    int u, v, w;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; i++){
        scanf("%d%d%d", &u, &v, &w);
        g[i] = (edge){u, v, w, i};
    }
    sort(g + 1, g + 1 + m, cmp);
    for(int i = 1; i <= n; i++)fa[i] = i;
    for(int i = 1; i <= m; i++){
        int u = g[i].u, v = g[i].v;
        if(find(u) == find(v))continue;
        uni(u, v);
        intree[g[i].id] = 1;
        add(u, v, i); add(v, u, i);
    }
    line[1] = 0;
    dfs(1, 0);
    dfs2(1, 1);
    //for(int i = 1; i <= n; i++)printf("%d %d %d\n", i, dep[i], top[i]);puts("");
    sort(g + 1, g + 1 + m, cmp_id);
    root = build();    

    for(int i = 1; i <= m; i++){
        if(intree[i])continue;
        int u = g[i].u, v = g[i].v;
        if(i == 473)fg = 1;
        int t = Query(u, v);
        ans[i] = t - 1;
        Modify(u, v, g[i].w - 1);
        fg = 0;
    }
    getdown();
    for(int i = 1; i <= m; i++)
        printf("%d ",ans[i] == oo ? -1 : ans[i]);
}

原文地址:https://www.cnblogs.com/EdSheeran/p/9543925.html

时间: 2024-10-31 15:48:59

暑假第二十六测的相关文章

暑假第二十五测

以后WA了T了看数组: 暑假四次数组下标超界,多次数组开小,暂时没有访问到负下标 题解: 第一题:这道题可以转换为颜色相同的点缩成一个点,每次可以将两个点合并成同一点,问最少几次将所有点合并成一个点: 开始想到并查集+贪心合并度数最多的并查集,但这样是有问题的,比如度数一样时,选择的先后顺序是有影响的: 正解:缩点+找直径,如果是一条黑白相间的链,就是点数/2, 而树上任何一条直径都会有一个点经过直径,我们从交点开始往外延伸,发现最长延伸就是直径本身: 思想:从特殊到一般 #include<bi

暑假第二十四测

题解: 第一题:二分+贪心:二分距离上限,两端的人能从两端取就从两端取,这样可以为中间的做贡献: #include<bits/stdc++.h> using namespace std; const int M = 10005; int a[M], b[M], pos[M], x, n, m; bool id[M]; #define ll long long inline int ab(int a, int b){ if(a > b)return a - b; return b - a;

暑假第二十九测

第三题换成能否得到x, 可以1, 不可以-1 题解: 第一题:打表找规律: 打表发现a是:1 1 2 2 3 4 4 4 5 6 6 7 8 8 8 8 9-- 对于每一项Ai = i拆分成质因数中有多少个2 + 1:如果把桶也给打出来,就发现他是这样的: 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 2 + 4 + 6 + 8 +  4  + 8 +  8 + 即2^i的等差数列,所以对一个数m我们就很容易确定他前面的数的和: 但是对于一个位置我们怎么找到他对应的m呢? 把上

第二十六篇:USB3.0高带宽ISO(48KBytes/125us)实战

USB3.1技术已经推出, 10Gbps的速率足以满足数据, HD视频传输的要求. 要步入USB3.1的研发, 还得将USB3.0的基础打扎实. 微软提供的SUPER MUTT只包含一个接口0, 其下有两个ALT, ALT 1与ALT 2, 分别包含了两对ISO IN/OUT端点, 不过, 只有ALT 2下的ISO OUT EP的bMaxBurst为1, 而其它三个ISO EP的bMaxBurst均为0, 而所有的ISO EP的Mult均为0. 即只有一个ISO EP支持2KBytes/125u

“全栈2019”Java多线程第二十六章:同步方法生产者与消费者线程

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多线程第二十六章:同步方法生产者与消费者线程 下一章 "全栈2019"Java多线程第二十七章:Lock获取lock/释放unlock锁 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorha

第二十六个知识点:描述NAF标量乘法算法

第二十六个知识点:描述NAF标量乘法算法 NAF标量乘法算法是标量乘法算法的一种增强,该算法使用了非邻接形式(Non-Adjacent Form)表达,减少了算法的期望运行时间.下面是具体细节: 让\(k\)是一个正整数,\(P\)是一个在域\(F_q\)上椭圆曲线\(E\)上的点.这个计算乘法操作\(Q = k * P\)就是圆曲线上的标量乘法操作(点乘).一个最简单计算的方法就是基于双倍-加法的霍纳规则的变体.顾名思义,该方法最突出的两个构建块是点加倍和点添加原语.就像名字那样,算法也十分简

【WPF学习】第二十六章 Application类——应用程序的生命周期

原文:[WPF学习]第二十六章 Application类--应用程序的生命周期 在WPF中,应用程序会经历简单的生命周期.在应用程序启动后,将立即创建应用程序对象,在应用程序运行时触发各种应用程序事件,你可以选择监视其中的某些事件.最后,当释放应用程序对象时,应用程序将结束. 一.创建Application对象 使用Application类的最简单方式是手动创建它.下面的示例演示了最小的程序:在应用程序入口(Main()方法)处创建名为MainWindow的窗口,并启动一个新的应用程序: 在本质

第二十六篇 知识点总结

虽然不是周末,但是这次我有空就来整理并回顾一下这一周所学的知识.... 这一周,我主要学习到 了Java中的一些基础知识,其中包括:接口.类.抽象类.继承.构造函数.方法重写.方法重载.自动转型.多态.引用传递: 下面 ,我就来一一总结一下,首先 先谈一下接口,什么是接口? Java接口 是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能). 它主要使用的关键字是----interface

python全栈开发基础【第二十六篇】(concurrent.futures模块、协程、Greenlet、Gevent)

注意 1.不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 2.只要你用并发,就会有锁的问题,但是你不能一直去自己加锁吧那么我们就用QUEUE,这样还解决了自动加锁的问题由Queue延伸出的一个点也非常重要的概念.以后写程序也会用到这个思想.就是生产者与消费者问题 一.Python标准模块--concurrent.futures(并发未来) concurent.future模块需要了解的 1.concurent