首页 > 其他分享 >『模拟赛』暑假集训CSP提高模拟25

『模拟赛』暑假集训CSP提高模拟25

时间:2024-08-20 21:38:18浏览次数:12  
标签:rt 25 ch return int qr CSP 模拟 mod

Rank

学新东西,不算挂分(确信。

image

A. 可持久化线段树

原板子[SP11470] TTM - To the moon

主席树,不过区间修改。

赛时想到标记永久化了,不过打 pushdown 的时候没新开点,于是 -100pts。

还挺简单的,建树和更改动态开点,按线段树来,加个 lazy,其他的就是普通线段树的操作。

板子
#include<bits/stdc++.h>
#define fo(x,y,z) for(register int (x)=(y);(x)<=(z);(x)++)
#define fu(x,y,z) for(register int (x)=(y);(x)>=(z);(x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
	char ch=getchar();lx x=0,f=1;
	for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
	return x*f;
}
#undef lx
#define qr qr()
#define fi first
#define se second
const int Ratio=0;
const int N=3e5+5;
const int mod=998244353;
int n,m,cnt;
int a[N],rot[N];
int son[N*32][2];
ll v[N*32],lazy[N*32];
namespace Wisadel
{
    #define ls (son[rt][0])
    #define rs (son[rt][1])
    #define mid ((l+r)>>1)
    int Wclone(int rt)
    {
        son[++cnt][0]=son[rt][0];
        son[cnt][1]=son[rt][1];
        v[cnt]=v[rt];
        lazy[cnt]=lazy[rt];
        return cnt;
    }
    void Wpushup(int rt)
    {
        v[rt]=(v[ls]+v[rs])%mod;
    }
    void Wpushdown(int rt,int l,int r)
    {
        ls=Wclone(ls),rs=Wclone(rs);
        lazy[ls]=(lazy[ls]+lazy[rt])%mod;
        lazy[rs]=(lazy[rs]+lazy[rt])%mod;
        v[ls]=(v[ls]+lazy[rt]*(((l+r)>>1)-l+1)%mod+mod)%mod;
        v[rs]=(v[rs]+lazy[rt]*(r-((l+r)>>1))%mod+mod)%mod;
        lazy[rt]=0;
    }
    int Wbuild(int rt,int l,int r)
    {
        rt=++cnt;
        if(l==r)
        {
            v[rt]=a[l];
            return rt;
        }
        ls=Wbuild(ls,l,mid),rs=Wbuild(rs,mid+1,r);
        Wpushup(rt);
        return rt;
    }
    int Wupd(int rt,int l,int r,int x,int y,int va)
    {
        rt=Wclone(rt);
        if(x<=l&&r<=y)
        {
            lazy[rt]=(lazy[rt]+va)%mod;
            v[rt]=(v[rt]+1ll*(r-l+1)*va%mod+mod)%mod;
            return rt;
        }
        if(lazy[rt]) Wpushdown(rt,l,r);
        if(x<=mid) ls=Wupd(ls,l,mid,x,y,va);
        if(y>mid) rs=Wupd(rs,mid+1,r,x,y,va);
        Wpushup(rt);
        return rt;
    }
    int Wq(int rt,int l,int r,int x,int y)
    {
        if(x<=l&&r<=y) return v[rt];
        if(lazy[rt]) Wpushdown(rt,l,r);
        ll res=0;
        if(x<=mid) res+=Wq(ls,l,mid,x,y);
        if(y>mid) res=(res+Wq(rs,mid+1,r,x,y))%mod;
        return res%mod;
    }
    short main()
    {
        // freopen(".in","r",stdin),freopen(".out","w",stdout);
        n=qr,m=qr;
        fo(i,1,n) a[i]=qr;
        rot[0]=Wbuild(1,1,n);
        int tim=0;
        fo(i,1,m)
        {
            int op=qr,x=qr,y,va;
            if(op==1) y=qr,va=qr,rot[++tim]=Wupd(rot[tim],1,n,x,y,va);
            else if(op==2) y=qr,printf("%d\n",Wq(rot[tim],1,n,x,y));
            else tim-=x;
        }
        return Ratio;
    }
}
int main(){return Wisadel::main();}

B. Little Busters !

签,不过 Tarjan。跟 Tarjan 真心不熟

赛时暴力寄寄,拿了特殊性质 40pts。

考虑正解,记下每种边,开局只连 lun 边,跑 Tarjan 找边双,边的两端点在同一边双就计入答案,然后考虑 qie 边,两端点不在同一边双就计入答案并将两边双合并,最后判断边双数量是否为 1,输出答案即可。

加练 Tarjan!

点击查看代码
#include<bits/stdc++.h>
#define fo(x,y,z) for(register int (x)=(y);(x)<=(z);(x)++)
#define fu(x,y,z) for(register int (x)=(y);(x)>=(z);(x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
	char ch=getchar();lx x=0,f=1;
	for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
	return x*f;
}
#undef lx
#define qr qr()
#define fi first
#define se second
const int Ratio=0;
const int N=2e5+5;
const int mod=998244353;
int n,m;
int hh[N],to[N<<1],ne[N<<1],cnt;
int dfn[N],low[N],tot,sccnt,ins[N],bl[N],fx[N];
vector<pair<int,int> >ans,lun,qie;
stack<int>s;
namespace Wisadel
{
    inline int Wfind(int x)
    {
        return fx[x]==x?x:fx[x]=Wfind(fx[x]);
    }
    void Wadd(int u,int v)
    {
        to[++cnt]=v;
        ne[cnt]=hh[u];
        hh[u]=cnt;
    }
    void Wtarjan(int u,int fa)
    {
        dfn[u]=low[u]=++tot;
        ins[u]=1;
        s.push(u);
        for(int i=hh[u];i!=-1;i=ne[i])
        {
            int v=to[i];
            if(v==fa) continue;
            if(!dfn[v])
                Wtarjan(v,u),low[u]=min(low[u],low[v]);
            else if(ins[v]==1) low[u]=min(low[u],dfn[v]);
        }
        if(dfn[u]==low[u])
        {
            int k=0;
            sccnt++;
            while(u!=k)
            {
                k=s.top();s.pop();
                ins[k]=0;
                bl[k]=sccnt;
            }
        }
    }
    void Wmerge(int x,int y,int id)
    {
        x=Wfind(x),y=Wfind(y);
        if(x!=y)
        {
            ans.push_back(qie[id]);
            fx[y]=x;
            sccnt--;
        }
    }
    short main()
    {
        n=qr,m=qr;
        memset(hh,-1,sizeof hh);
        fo(i,1,m)
        {
            int a=qr,b=qr;string s;cin>>s;
            if(s=="Lun") Wadd(a,b),Wadd(b,a),lun.push_back(make_pair(a,b));
            if(s=="Qie") qie.push_back(make_pair(a,b));
        }
        fo(i,1,n)
        {
            if(!dfn[i]) Wtarjan(i,0);
            fx[i]=i;
        }
        fo(i,0,(int)lun.size()-1)
            if(bl[lun[i].fi]==bl[lun[i].se]) ans.push_back(lun[i]);
        fo(i,0,(int)qie.size()-1)
            if(bl[qie[i].fi]!=bl[qie[i].se]) Wmerge(bl[qie[i].fi],bl[qie[i].se],i);
        if(sccnt!=1) printf("NO\n");
        else
        {
            printf("YES\n%d\n",ans.size());
            fo(i,0,ans.size()-1)
                printf("%d %d\n",ans[i].fi,ans[i].se);
        }
        return Ratio;
    }
}
int main(){return Wisadel::main();}

C. 魔卡少女樱

[ABC276G] Count Sequences

计数题。

赛时打表拿了 45pts,感觉还行。

考虑正解。由于相邻两数模 3 意义下不同余,所以考虑差分,记下相邻两数差模 3 的值,显然不能为 0,因此只有 1 和 2 两种可能。当然可以在查分数组中插入 3,仍能保证合法。我们枚举这里面 2 的个数,再根据差分的性质:和为序列最后的数,即和 \(\le m\),可以求得最多插入 3 的个数,进而总和成答案。

具体见下(有点漏洞,比如这里没有算上开始枚举的 \(a_1\) 即差分数组中第一个数的值):

image

点击查看代码
#include<bits/stdc++.h>
#define fo(x,y,z) for(register int (x)=(y);(x)<=(z);(x)++)
#define fu(x,y,z) for(register int (x)=(y);(x)>=(z);(x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
	char ch=getchar();lx x=0,f=1;
	for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
	return x*f;
}
#undef lx
#define qr qr()
#define fi first
#define se second
const int Ratio=0;
const int N=2e7+5;
const int mod=998244353;
int n,m;
ll jc[N],ny[N],sum[N],ans;
namespace Wisadel
{
    ll Wqp(ll x,int y)
    {
        ll res=1;
        while(y){if(y&1) res=res*x%mod; x=x*x%mod; y>>=1;}
        return res;
    }
    ll C(int n,int m)
    {
        if(n>m) return 0;
        if(!n) return 1;
        return jc[m]*ny[m-n]%mod*ny[n]%mod;
    }
    short main()
    {
        n=qr,m=qr;
        jc[0]=sum[0]=ny[0]=1;
        fo(i,1,N-3) jc[i]=jc[i-1]*i%mod;
        ny[N-3]=Wqp(jc[N-3],mod-2);
        fu(i,N-4,1) ny[i]=ny[i+1]*(i+1)%mod;
        fo(i,1,m-1) sum[i]=(sum[i-1]+C(n-1,n+i-1))%mod;
        fo(i,0,2)
            for(int j=0;j<n&&j+n-1+i<=m;j++)
                ans=(ans+C(j,n-1)*sum[(m-j-n+1-i)/3]%mod+mod)%mod;
        printf("%lld\n",ans);
        return Ratio;
    }
}
int main(){return Wisadel::main();}

D. 声之形

挺牛的题,甚至因为题面的细节饭堂了

image

这怎么看也很难想到 \(x\) 可以不是序列里的元素啊啊啊,挂 10pts。

最后几场了,想好好打打,不过时间提早半个小时有种刚从被窝钻出来就上战场的感觉。

算上 T1 能到前十,差不多稳定吧。

还有就是迷之主席树开 64 倍空间仍然过不去,对拍还拍不出来,最后还是 5k 来了发现了问题,sto%%% 5k %%%orz!得出的结论是区间修改主席树应该放肆开空间,只要不 MLE 往大了开就行,大概 \(10^7\) 左右吧,直接被控一下午,看不到我提交是因为我没 spoj 的号,用丁真号交的,最后打了两种,有无 pushdown 的都过了,爽。


完结撒花~

标签:rt,25,ch,return,int,qr,CSP,模拟,mod
From: https://www.cnblogs.com/Ratio-Yinyue1007/p/18370366

相关文章

  • CSP 模拟 25
    T1可持久化线段树做法一:注意到\(\sumk<n\),所以数据结构直接暴力回溯是对的,然后做完了。做法二:还是注意到那个,记一下修改过的节点,然后回溯直接改节点。做法三:主席树区间修改,一直想写,但是好像没啥用这个东西,tothemoon是板子,我想抽时间玩玩tothemoonT2LittleBusters!......
  • 暑假集训CSP提高模拟25
    赛时rank5,T1100,T285,T350,T45T2Tarjan意外挂了,在Tarjan里判割边会挂?T3\(O(nm^2)\)暴力能拿50?特判样例能拿60?可持久化线段树没啥好说的,主席树板子。点此查看代码#include<bits/stdc++.h>#include<bits/extc++.h>//usingnamespace__gnu_pbds;//usingnames......
  • 【四旋翼】四旋翼无人机的几何跟踪控制(含弹道 位置误差 速度误差)【含Matlab源码 7256
    ✅博主简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,Matlab项目合作可私信或扫描文章底部QQ二维码。......
  • 【图像加密解密】6维超混沌系统和DNA编码的图像加密解密【含Matlab源码 7257期】
    ✅博主简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,Matlab项目合作可私信或扫描文章底部QQ二维码。......
  • 【2025毕设热门选题】《基于SpringBoot+Vue的校园资产管理系统》功能规划和开题报告
    博主介绍:8年资深码农、211小硕,全网10万+粉丝。文科生转码,所以非常懂小白学习历程。java领域优质创作者,擅长小白基础课程教学和项目讲解辅导。专注于Java技术领域和大学生毕业项目实战讲解已经5年,服务10000+小白客户。技术范围:自己手撸SpringBoot、Vue、javaweb网站、小程......
  • 【Leetcode 1365 】 有多少小于当前数字的数字 —— 数组模拟哈希表(就没写过这么详细
    给你一个数组 nums,对于其中每个元素 nums[i],请你统计数组中比它小的所有数字的数目。换而言之,对于每个 nums[i] 你必须计算出有效的 j 的数量,其中 j 满足 j!=i 且 nums[j]<nums[i] 。以数组形式返回答案。示例1:输入:nums=[8,1,2,2,3]输出:[4,0,1,1,3]解......
  • CSP 2023 普及组第一轮 - CSP/J 2023初试题详细解析
    基础选择题:CSP2023普及组第一轮-CSP/S2023初试题基础部分解析-CSDN博客程序阅读第一题:CSP2023普及组第一轮-CSP/S2023初试题程序阅读第一题解析-CSDN博客程序阅读第二题:CSP2023普及组第一轮-CSP/S2023初试题程序阅读第二题解析-CSDN博客程序阅读第三......
  • 暑假集训CSP提高模拟 25
    暑假集训CSP提高模拟25组题人:@KafuuChinocpp|@H_Kaguya\(T1\)P235.可持久化线段树\(0pts\)弱化版:SP11470TTM-Tothemoon标记永久化主席树板子。点击查看代码constllp=998244353;lla[100010];structPDS_SMT{ llroot[100010],rt_sum; structSegme......
  • delphi加密C#解密(AES-256)
    因为公司内部业务需要,用delphi加密的内容(流和字符串)要用C#解密,因为不懂delphi,我这里只是问同事要了代码,贴上delphi加密:共两个文件(AES.pas和ElAES.pas)AES.pas:(**************************************************************)(*......
  • 模拟费用流
    模拟费用流是什么考虑一般的单路增广费用流流程,就是一直去寻找最小/最大费用增广路的过程。但是寻找一条增广路往往需要最短路算法,这造成了很大的时间开销。找到增广路的方式不唯一,可以通过别的手段去寻找增广路。在一些特殊网络中可以获得更加优秀的时间复杂度。QOJ7185题目......