25年csp认证题解

CSP202509C. HTTP 头信息

比较沟槽的一道模拟题。

只是单纯体面长,恶心人罢了。

deque一切好说。

struct Node {
    char data;
    shared_ptr<Node> left;
    shared_ptr<Node> right;

    Node(char d) : data(d), left(nullptr), right(nullptr) {}
    Node() : data('\0'), left(nullptr), right(nullptr) {}
};

shared_ptr<Node> rebuildHuffmanTree(const string& s, int& index) {
    if (index >= s.length()) return nullptr;

    if (s[index] == '1') {
        index++; // 跳过'1'
        char ch = s[index++]; // 读取字符
        return make_shared<Node>(ch);
    } else if (s[index] == '0') {
        index++; // 跳过'0'
        auto node = make_shared<Node>();
        node->left = rebuildHuffmanTree(s, index);
        node->right = rebuildHuffmanTree(s, index);
        return node;
    }
    return nullptr;
}

// 辅助函数:打印树结构(前序遍历)
unordered_map<string,char>mp;
void printTree(const shared_ptr<Node>& root, string prefix = "") {
    if (!root) return;

    if (root->data != '\0') {
        //cout << prefix << "Leaf: " << root->data << endl;
        mp[prefix]=root->data;
        //cout<<prefix<<" "<<root->data<<endl;
    } else {
        //cout << prefix << "Internal Node" << endl;
    }
    printTree(root->left, prefix + "0");
    printTree(root->right, prefix + "1");
}

int s,d;
deque<pair<string,string> >dq;
string ky[500],val[500];
string encodedTree;
inline string clac(string ss){
    if(ss[0]!='H')return ss;
    if(ss[0]=='H'&&ss[1]=='H')return ss.substr(1);
    int tmp=0;
    vector<int>v;
    for(int i=1;i<ss.size()-2;i++){
        if(isdigit(ss[i]))tmp=ss[i]-'0';
        else if(islower(ss[i]))tmp=ss[i]-'a'+10;
        vector<int>h;
        while(tmp)h.push_back(tmp%2),tmp/=2;
        while(h.size()<4)h.push_back(0);
        reverse(h.begin(),h.end());
        for(auto x:h)v.push_back(x);
    }
    int t=ss.back()-'0';
    while(t--)v.pop_back();
    string ans,tmp2;
    for(int i=0;i<v.size();i++){
        //cout<<v[i]<<" ";
        tmp2+=v[i]+'0';
        if(mp.count(tmp2)){
            ans+=mp[tmp2];
            tmp2="";
        }
    }
    //cout<<endl;
    return ans;
}
signed main(){
    std::ios::sync_with_stdio(false);std::cin.tie(nullptr);cout.tie(0);
    // 示例:0表示内部节点,1表示叶子节点
    
    cin>>s>>d;
    up(i,1,s){
        cin>>ky[i]>>val[i];
    }
    cin>>encodedTree;
    //cout<<encodedTree<<endl;
    int index = 0;
    auto root = rebuildHuffmanTree(encodedTree, index);
    //cout << "Rebuilt Huffman Tree:" << endl;
    printTree(root);
    int n;
    cin>>n;
    int op,pos;
    while(n--){
        cin>>op;
        if(op==1){
            cin>>pos;
            if(pos>=1&&pos<=s){
                cout<<ky[pos]<<": "<<val[pos]<<endl;
            }
            else {
                cout<<dq[pos-s-1].fi<<": "<<dq[pos-s-1].se<<endl;
            }
        }
        else if(op==2){
            string s1,s2;
            cin>>pos;
            if(pos==0){
                cin>>s1>>s2;
                s1=clac(s1);s2=clac(s2);

                
            }
            else{
                cin>>s2;
                s2=clac(s2);
                if(pos<=s)s1=ky[pos];
                else s1=dq[pos-s-1].fi;
            }
            cout<<s1<<": "<<s2<<endl;
            dq.push_front({s1,s2});
            if(dq.size()>d)dq.pop_back();
        }
        else if(op==3){
            string s1,s2;
            int pos2;
            cin>>pos;
            if(pos==0){
                cin>>s1>>s2;
                s1=clac(s1);s2=clac(s2);
            }
            else{
                cin>>s2;
                s2=clac(s2);
                if(pos<=s)s1=ky[pos];
                else s1=dq[pos-s-1].fi;
            }
            cout<<s1<<": "<<s2<<endl;
        }
    }
    return 0;
}         
  

CSP202509D 造题计划(上)

基础的数据结构。

让我们在树上求一条链上的\(\mex\)

考虑主席树,按照dfs序加点。

最后相减就行了。

int n,m;
int a[N];
vector<int>g[N];
int fa[N],sz[N],son[N],dep[N];
int top[N],id[N],idx,b[N];
struct PSTree{
    struct node{
        int ls,rs,sum;
    }tr[N<<5];
    int cnt,rt[N];
    void insert(int &k,int pre,int l,int r,int x,int y){
        k=++cnt;
        tr[k]=tr[pre];tr[k].sum++;
        if(l==r)return;
        int mid=(l+r)>>1;
        if(mid>=x)insert(tr[k].ls,tr[pre].ls,l,mid,x,y);
        if(mid<y)insert(tr[k].rs,tr[pre].rs,mid+1,r,x,y);
    }
    inline void init(){
        //up(i,1,idx)insert(rt[i],rt[i-1],0,n-1,b[i],b[i]);    
    }
    int ask(int u,int v,int h,int fh,int l,int r){
        if(l==r)return tr[u].sum+tr[v].sum-tr[h].sum-tr[fh].sum?l+1:l;
        int mid=(l+r)>>1,tmp=tr[tr[u].ls].sum+tr[tr[v].ls].sum-tr[tr[h].ls].sum-tr[tr[fh].ls].sum;
        if(tmp<mid-l+1)return ask(tr[u].ls,tr[v].ls,tr[h].ls,tr[fh].ls,l,mid);
        else return ask(tr[u].rs,tr[v].rs,tr[h].rs,tr[fh].rs,mid+1,r);
    }
    inline int ans(int x,int y,int h){
        return ask(rt[x],rt[y],rt[h],rt[fa[h]],0,n-1);
    }
}T;

void dfs1(int u,int from){
    fa[u]=from;sz[u]=1;
    dep[u]=dep[from]+1;
    T.insert(T.rt[u],T.rt[from],0,n-1,a[u],a[u]);
    for(auto v:g[u]){
        if(v==from)continue;
        dfs1(v,u);
        sz[u]+=sz[v];
        if(sz[son[u]]<sz[v])son[u]=v;
    }
}

void dfs2(int u,int tp){
    top[u]=tp;id[u]=++idx;
    b[idx]=a[u];
    if(son[u])dfs2(son[u],tp);
    for(auto v:g[u]){
        if(v==fa[u]||v==son[u])continue;
        dfs2(v,v);
    }
}
inline int lca(int u,int v){
    while(top[u]!=top[v]){
        if(dep[top[u]]>dep[top[v]])u=fa[top[u]];
        else v=fa[top[v]];
    }
    return dep[u]<dep[v]?u:v;
}

signed main(){
    std::ios::sync_with_stdio(false);std::cin.tie(nullptr);cout.tie(0);
    cin>>n>>m;
    up(i,1,n)cin>>a[i];
    int u,v;
    up(i,1,n-1){
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs1(1,0);
    dfs2(1,1);
    int x,y;
    //T.init();
    while(m--){
        cin>>x>>y;
        int h=lca(x,y);
        cout<<T.ans(x,y,h)<<endl;
    }
    return 0;
}         
posted @ 2025-12-04 21:09  LiQXing  阅读(0)  评论(0)    收藏  举报