暑假第二十六测

时间:2022-12-13 19:43:19

今天又考的奇差

暑假第二十六测

暑假第二十六测

暑假第二十六测

 

 题解:

第一题;

暑假第二十六测

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

暑假第二十六测暑假第二十六测
#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);
}
View Code

 

第二题:我们发现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);
        }
    }
}
View Code

 

第三题:

暑假第二十六测

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

#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]);
}