StOI-1

P6373 「StOI-1」IOI计数

线段树维护区间内 1 0 01 10 101 个数即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e5+5;
struct seg
{
    ll a,b,c,d,e;
    // 0 1 01 10 101
}tr[maxn<<2];
int n,m;
char s[maxn];
#define lson now<<1
#define rson now<<1|1
void pushup(int now)
{
    tr[now].a=tr[lson].a+tr[rson].a;
    tr[now].b=tr[lson].b+tr[rson].b;
    tr[now].c=tr[lson].c+tr[rson].c+tr[lson].a*tr[rson].b;
    tr[now].d=tr[lson].d+tr[rson].d+tr[lson].b*tr[rson].a;
    tr[now].e=tr[lson].e+tr[rson].e+tr[lson].d*tr[rson].b+tr[lson].b*tr[rson].c;
}
void build(int now,int l,int r)
{
    if(l==r)
    {
        if(s[l]=='I') tr[now].b=1;
        else tr[now].a=1;
        return;
    }
    int mid=l+r>>1;
    build(lson,l,mid); build(rson,mid+1,r);
    pushup(now);
}
void modify(int now,int l,int r,int pos,int val)
{
    if(l==r)
    {
        if(val) tr[now].b=1,tr[now].a=0;
        else tr[now].a=1,tr[now].b=0;
        return;
    }
    int mid=l+r>>1;
    if(pos<=mid) modify(lson,l,mid,pos,val);
    else modify(rson,mid+1,r,pos,val);
    pushup(now);
}
seg merge(seg x,seg y)
{
    seg res;
    res.a=x.a+y.a; res.b=x.b+y.b;
    res.c=x.c+y.c+x.a*y.b;
    res.d=x.d+y.d+x.b*y.a;
    res.e=x.e+y.e+x.b*y.c+x.d*y.b;
    return res;
}
seg query(int now,int l,int r,int L,int R)
{
    if(l>=L && r<=R) return tr[now];
    int mid=l+r>>1;
    if(R<=mid) return query(lson,l,mid,L,R);
    if(mid<L) return query(rson,mid+1,r,L,R);
    return merge(query(lson,l,mid,L,R),query(rson,mid+1,r,L,R));
}
int main()
{
    // freopen("a.in","r",stdin);
    // freopen("a.out","w",stdout);
    scanf("%d%d",&n,&m);
    scanf("%s",s+1);
    build(1,1,n);
    for(int i=1;i<=m;i++)
    {
        int op,x,y;
        char cc[5];
        scanf("%d%d",&op,&x);
        if(op==1)
        {
            scanf("%s",cc);
            if(cc[0]=='I') y=1;
            else y=0;
            modify(1,1,n,x,y);
        }
        else
        {
            scanf("%d",&y);
            printf("%lld\n",query(1,1,n,x,y).e);
        }
    }
    return 0;
}

P6374 「StOI-1」树上询问

先随便以一个点为根计算,不妨设1为根
如果z不在x-y的路径上,那么一定不可以
否则,答案就是从z所有子节点包括父亲那个方向上的,减去x和y两个方向的儿子即可,画画图就可以理解了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e5+5;
int n,q;
vector <int> G[maxn];
int dfn[maxn],dfstime;
int dep[maxn],fa[maxn][21],siz[maxn];
void dfs(int u,int f)
{
    fa[u][0]=f; dep[u]=dep[f]+1; siz[u]=1;
    dfn[u]=++dfstime;
    for(int i=1;i<=20;i++) fa[u][i]=fa[fa[u][i-1]][i-1];
    for(auto to:G[u])
    {
        if(to==f) continue;
        dfs(to,u);
        siz[u]+=siz[to];
    }
}
int LCA(int x,int y)
{
    if(dep[x]<dep[y]) swap(x,y);
    for(int i=20;i>=0;i--) if(dep[fa[x][i]]>=dep[y]) x=fa[x][i];
    if(x==y) return x;
    for(int i=20;i>=0;i--) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
    return fa[x][0];
}
int get(int x,int top)
{
    if(x==top) return 0;
    for(int i=20;i>=0;i--) if(dep[fa[x][i]]>dep[top]) x=fa[x][i];
    return siz[x];
}
bool in(int x,int y)
{
    if(dfn[x]>=dfn[y] && dfn[x]<=dfn[y]+siz[y]-1) return true;
    return false;
}
int main()
{
    // freopen("a.in","r",stdin);
    // freopen("a.out","w",stdout);
    scanf("%d%d",&n,&q);
    int x,y,z;
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&x,&y);
        G[x].push_back(y);
        G[y].push_back(x);
    }
    dfs(1,0);
    for(int i=1;i<=q;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        int lca=LCA(x,y);
        if(z==lca){printf("%d\n",n-get(x,z)-get(y,z)); continue;}
        if(in(z,lca) && in(x,z)){printf("%d\n",siz[z]-get(x,z)); continue;}
        if(in(z,lca) && in(y,z)){printf("%d\n",siz[z]-get(y,z)); continue;}
        printf("0\n");
    }
    return 0;
}

P6375 「StOI-1」小Z的旅行

发现同种高度的山的转移比较特别,所以我们每次把同种高度的山拿出来转移
因为题目限制了同种高度的山只能走一次
fu,guf_u,g_ufu,gu分别表示随意走的期望和不走相同高度山的期望
那么我们对于同一高度的若干山,先转移出g,然后去计算f即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=5e5+5;
int n;
struct va
{
    int v,id;
}a[maxn];
bool cmp(va x,va y)
{
    return x.v<y.v;
}
ll f[maxn],g[maxn];
int lowbit(int x)
{
    return x&(-x);
}
ll qpow(ll a,ll b)
{
    ll res=1;
    while(b)
    {
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
void add(ll &x,ll y){x=(x+y)%mod;}
void sus(ll &x,ll y){x=(x+mod-y)%mod;}
struct bit
{
    ll c[maxn];
    void Add(int x,int val)
    {
        while(x<=n)
        {
            add(c[x],val);
            x+=lowbit(x);
        }
    }
    ll query(int x)
    {
        ll res=0;
        while(x)
        {
            add(res,c[x]);
            x-=lowbit(x);
        }
        return res;
    }
}A,B;
ll sumf,dist[maxn];
ll ask(int pos)
{
    ll res=0;
    add(res,(A.query(pos)*pos%mod-B.query(pos)+mod)%mod);
    add(res,((B.query(n)-B.query(pos)+mod)%mod-(A.query(n)-A.query(pos))*pos%mod+mod)%mod);
    return res;
}
int main()
{
    // freopen("a.in","r",stdin);
    // freopen("a.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i].v),a[i].id=i;
    sort(a+1,a+n+1,cmp);
    for(int i=1,j;i<=n;i=j+1)
    {
        j=i; ll he=0;
        while(a[j+1].v==a[j].v) j++;
        for(int k=i;k<=j;k++)
        {
            dist[k]=ask(a[k].id);
            g[k]=(sumf+dist[k])*qpow(i-1,mod-2)%mod;
            he+=g[k];
        }   
        for(int k=i;k<=j;k++) A.Add(a[k].id,1),B.Add(a[k].id,a[k].id);
        for(int k=i;k<=j;k++)
        {
            ll tmp=((he+ask(a[k].id)-g[k]-dist[k])%mod+mod)%mod*qpow(j-i,mod-2)%mod;
            f[k]=(tmp*(j-i)%mod+g[k]*(i-1)%mod)%mod*qpow(j-1,mod-2)%mod;
            add(sumf,f[k]);
        }
    }
    printf("%lld\n",f[n]);
    return 0;
}
本系统旨在构建一套面向高等院校的综合性教务管理平台,涵盖学生、教师及教务处三个核心角色的业务需求。系统设计着重于实现教学流程的规范化与数据处理的自动化,以提升日常教学管理工作的效率与准确性。 在面向学生的功能模块中,系统提供了课程选修服务,学生可依据培养方案选择相应课程,并生成个人专属的课表。成绩查询功能支持学生查阅个人各科目成绩,同时系统可自动计算并展示该课程的全班最高分、平均分、最低分以及学生在班级内的成绩排名。 教师端功能主要围绕课程与成绩管理展开。教师可发起课程设置申请,提交包括课程编码、课程名称、学分学时、课程概述在内的新课程信息,亦可对已开设课程的信息进行更新或撤销。在课程管理方面,教师具备录入所授课程期末考试成绩的权限,并可导出选修该课程的学生名单。 教务处作为管理中枢,拥有课程审批与教学统筹两大核心职能。课程设置审批模块负责处理教师提交的课程申请,管理员可根据教学计划与资源情况进行审核批复。教学安排模块则负责全局管控,包括管理所有学生的选课最终结果、生成包含学号、姓名、课程及成绩的正式成绩单,并能基于选课与成绩数据,统计各门课程的实际选课人数、最高分、最低分、平均分以及成绩合格的学生数量。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
05-26
### C++ 中 `stoi` 函数的用法 在 C++ 中,`std::stoi` 是一个用于将字符串转换为整数的标准库函数。它定义于头文件 `<string>` 中,并提供了多种重载形式来支持不同的输入格式和基数。 以下是 `std::stoi` 的基本语法: ```cpp int stoi(const std::string& str, size_t* pos = nullptr, int base = 10); ``` #### 参数说明 - **str**: 要被解析的字符串。 - **pos** (可选): 如果提供此参数,则会存储第一个无法转换字符的位置索引。 - **base** (可选): 解析时使用的数值进制,默认为十进制(即 10)。可以设置其他值,比如二进制(2)、八进制(8)或十六进制(16)[^4]。 #### 返回值 返回从字符串中提取到的第一个有效的整数值。如果未能找到有效整数或者超出范围,则抛出异常。 #### 常见异常 - **invalid_argument**: 当传入的字符串不包含任何合法数字序列时触发。 - **out_of_range**: 若结果超出了目标类型的表示范围则引发该错误。 下面给出几个具体的例子展示如何正确运用这个功能: ```cpp #include <iostream> #include <string> int main(){ try { std::string s1 = "123"; std::string s2 = "-456"; std::string s3 = "abc"; // This will throw invalid_argument exception. int num1 = std::stoi(s1); int num2 = std::stoi(s2); std::cout << "String '" << s1 << "' converted to integer: " << num1 << "\n"; std::cout << "String '" << s2 << "' converted to integer: " << num2 << "\n"; // Attempting conversion of non-numeric string which should fail gracefully with proper error handling. int num3 = std::stoi(s3); } catch(std::invalid_argument const &e){ std::cerr<<"Invalid argument provided.\n"; }catch(std::out_of_range const &e){ std::cerr<<"Value out of range.\n"; } } ``` 以上程序展示了标准情况下以及当遇到非法输入时的行为模式。通过捕获可能发生的两种主要类型异常(`std::invalid_argument`, `std::out_of_range`),我们可以更稳健地处理各种潜在问题[^4]。 ### 注意事项 尽管 `std::stoi` 提供了一种简单的方法来进行字符串转整型操作,但在实际应用过程中仍需注意一些细节以避免不必要的麻烦: - 确保源数据确实是可以解释成相应数值的数据片段; - 对可能出现的各种边界条件要有足够的预见性和应对措施;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值