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

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

时间:2024-08-14 21:04:41浏览次数:14  
标签:ch return int tot qr ans 20 CSP 模拟

Rank

有点可惜,暴力打满就并列 Rank1 了。

image

A. Kanon

原[JOI 2021 Final] 雪玉

签。

考虑到每两个球之间的距离是恒不变的,因此我们可以通过找到每个球控制的边界得到答案,每个区间正好可以得出左边球的右边界和右边球的左边界。

记录每个区间的标号和长度,按长度升序 sort 一遍,然后记录总体位移的状态,记录向右的最远距离和向左的最远距离,二者之和大于等于区间长度时,该区间对应的两个球分别的右左边界就确定了。

每个区间只会遍历到一次,总体的复杂度集中在 sort 上,大概是 \(\mathcal{O(n\log n)}\)。

点击查看代码
#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()
const int Ratio=0;
const int N=3e5+5;
int n,q;
ll tot,lmin,rmax,a[N],L[N],R[N];
bool yzl[N],yzr[N];
struct rmm
{// qujian
	int id;ll dis;
}d[N];
bool cmp(rmm a,rmm b){return a.dis<b.dis;}
namespace Wisadel
{
    short main()
    {
        // freopen("Kanon1.in","r",stdin),freopen(".out","w",stdout);
        n=qr,q=qr;
        fo(i,1,n)
        {
            a[i]=qr;
            if(i>1) d[i-1].dis=a[i]-a[i-1],d[i-1].id=i-1;
        }
        sort(d+1,d+n,cmp);
        int now=1;
        fo(i,1,q)
        {
            ll w=qr;tot+=w;
            if(tot>0) rmax=max(rmax,tot);
            else lmin=min(lmin,tot);
            while(now<=n-1&&rmax-lmin>=d[now].dis)
            {
                int xi=d[now].id,xj=xi+1;
                if(tot>0) L[xj]=a[xj]+lmin,R[xi]=L[xj];
                else R[xi]=a[xi]+rmax,L[xj]=R[xi];
                yzl[xj]=1,yzr[xi]=1;now++;
            }
        }
        fo(i,1,n)
        {
            if(!yzl[i]) L[i]=a[i]+lmin;
            if(!yzr[i]) R[i]=a[i]+rmax;
            printf("%lld\n",R[i]-L[i]);
        }
        return Ratio;
    }
}
int main(){return Wisadel::main();}

B. Summer Pockets

原[ARC157D] YY Garden

第一次拿首 A。

感觉有点偏思维,不过推出几个重要性质后还是蛮简单的。

首先记 Y 的总数 \(tot\),若为奇数一定无解。

已知两个 Y 分一组,那么一共有 \(\frac{tot}{2}\) 组。我们将该矩阵分成若干个矩形,比较显然的是,知道了行被分成了几组,就能知道列被分成了几组。

我们可以枚举它,不过我枚举的是行被分成若干组后,每一组含 Y 的个数 \(hk\),而我们知道两个 Y 一组,所以就能知道列被分成了 \(\frac{hk}{2}\) 部分,根据矩形面积公式,我们就能得到行应当被分成 \(\frac{tot\times 2}{hk}\) 部分;这里具体枚举那个都是无关紧要的,因为已知其中一个的值就能推导出剩下的值。

注意上面描述的时候用了应当,这是因为以上情况只是我们假设出来的理想情况,若与之不符则应当舍弃;此外,还有一个判断无解的标准,就是我们在按以上情况分出各部分后,需要判断每部分是否正好含两个 Y,具体实现我们可以借助二维前缀和维护。

之后方案若仍合法,则开始计数,此时我们划分部分就较为宽松了,在上面判断的时候,我们划分的标准是该行 / 列有 Y 出现且能将行 / 列分成每部分含对应数量的一组,而计数时只要不影响划分的状态都可以计入,最终利用乘法原理计算出该方案的所有方案数计入答案即可。

由于基础方案数比较少,所以原本 \(\mathcal{O(S)}\) 的时间复杂度降到了很低。

新鲜的题解点点赞感谢捏~

点击查看代码
#include<bits/stdc++.h>

const int Ratio=0;
const int N=2005;
const int mod=998244353;
int n,m,tot;
int sum[N][N],hsum[N],lsum[N],hang[N],lie[N];
int hzc[N],lzc[N],cnth[N],cntl[N];
int ans;
namespace Wisadel
{
    void Wsol(int hk)
    {
        int lk=tot*2/hk,ch=0,cl=0,res=1;
        for(int i=1;i<=n;i++) if(hang[i]&&hsum[i]%hk==0) hzc[++ch]=i;
        for(int i=1;i<=m;i++) if(lie[i]&&lsum[i]%lk==0) lzc[++cl]=i;
        if(2*ch!=lk||2*cl!=hk) return;
        for(int i=1;i<=ch;i++) for(int j=1;j<=cl;j++)
        {
            int ck=sum[hzc[i]][lzc[j]]-sum[hzc[i-1]][lzc[j]]-sum[hzc[i]][lzc[j-1]]+sum[hzc[i-1]][lzc[j-1]];
            if(ck!=2) return;
        }
        std::fill(cnth+1,cnth+1+ch,0),std::fill(cntl,cntl+1+cl,0);
        for(int i=1;i<=n;i++) if(hsum[i]%hk==0) cnth[hsum[i]/hk]++;
        for(int i=1;i<=m;i++) if(lsum[i]%lk==0) cntl[lsum[i]/lk]++;
        for(int i=1;i<ch;i++) res=1ll*res*cnth[i]%mod;
        for(int i=1;i<cl;i++) res=1ll*res*cntl[i]%mod;
        ans=(ans+res)%mod;
    }
    short main()
    {
        scanf("%d%d",&n,&m);getchar();
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                char ch=getchar();
                sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
                if(ch=='Y') hang[i]++,lie[j]++,hsum[i]++,lsum[j]++,sum[i][j]++;
            }
            getchar();
            hsum[i]+=hsum[i-1];
        }
        for(int i=1;i<=m;i++) lsum[i]+=lsum[i-1];
        tot=hsum[n];
        if(tot&1){printf("0\n");return Ratio;}
        for(int i=2;i<=n*m;i+=2)
        {
            if(tot%i==0) Wsol(i);
            if(i>tot) break;
        }
	    printf("%d\n",ans%mod);
        return Ratio;
    }
}
int main(){return Wisadel::main();}

C. 空之境界

原Gym103469D Deleting

饭堂的一题,最简单的区间 dp 暴力想不到。

纯搜 + 打表样例拿到 10pts。其实赛时想到 dp 了,但真想不起来区间 dp,看来该补补了。

60pts 代码
#define fuck printf("################33\n");
#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()
const int Ratio=0;
const int N=4005;
const int mod=998244353;
int n,f[N][N],w[N][N];
namespace Wisadel
{
    int Wdfs(int x,int y)
    {
        if(f[x][y]||x>=y) return f[x][y];
        int ans=mod;
        for(int i=x+1;i<=y;i+=2)
            ans=min(ans,max({w[x][i],Wdfs(x+1,i-1),Wdfs(i+1,y)}));
        return f[x][y]=ans;
    }
    short main()
    {
        // freopen(".in","r",stdin),freopen(".out","w",stdout);
        n=qr;
        fo(i,1,n) for(int j=i+1;j<=n;j+=2) w[i][j]=qr;
        printf("%d\n",Wdfs(1,n));
        return Ratio;
    }
}
int main(){return Wisadel::main();}

D. 穗

原[Ynoi2016] 镜中的昆虫 我何德何能现在就做上 ynoi 的题了

猜猜我为什么现在才发记录。

扫了一眼,啊!\(\huge{带修莫队!}\)made 这不是我写博客时直接忽视的东西吗wwwww (再也不骑士某个算法了

只拿到了 20pts 的\(\mathcal{O(nm)}\) 暴力分,另外 20pts 不带修的一眼放普通莫队过的,结果又饭堂,离散化后没有直接赋值到原数组上,每次都 lower_bound 一遍导致复杂度直接乘上一个 \(\log n\) 导致爆炸。

然后重温了一下午的带修莫队,被数颜色卡了 5 个 h,最后也是发现一个堂食错误然后过了啊。

80pts 代码

200 行,比正解都长

#define fuck printf("################33\n");
#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()
const int Ratio=0;
const int N=1e6+5;
const int mod=998244353;
int n,m,tot;
int a[N],b[N];
struct rmm
{
    int op,l,r,x,id;
}q[N];
namespace Wistask1
{
    map<int,int>mp;
    int ans=0;
    short main()
    {
        while(m--)
        {
            int op=qr,l=qr,r=qr,x;
            if(op==1)
            {
                x=qr;
                fo(i,l,r) a[i]=x;
            }
            else
            {
                mp.clear();ans=0;
                fo(i,l,r)
                {
                    if(!mp[a[i]]) ans++,mp[a[i]]++;
                    mp[a[i]]++;
                }
                printf("%d\n",ans);
            }
        }
        return Ratio;
    }
}
namespace Wistask2
{
    int b[N],ed[N],bl[N],ans[N],anss,num[N];
    bool cmp(rmm a,rmm b)
    {
        if(bl[a.l]==bl[b.l])
        {
            if(bl[a.l]&1) return a.r<b.r;
            return a.r>b.r;
        }
        return a.l<b.l;
    }
    void Wadd(int x)
    {
        if(!num[a[x]]) anss++;
        num[a[x]]++;
    }
    void Wdel(int x)
    {
        num[a[x]]--;
        if(!num[a[x]]) anss--;
    }
    short main()
    {
        fo(i,1,n) b[i]=a[i];
        sort(b+1,b+1+n);
        int tot=unique(b+1,b+1+n)-b-1;
        fo(i,1,n) a[i]=lower_bound(b+1,b+1+tot,a[i])-b;
        int sq=sqrt(n);
        fo(i,1,sq) ed[i]=n/sq*i;
        ed[sq]=n;
        fo(i,1,sq) fo(j,ed[i-1]+1,ed[i]) bl[j]=i;
        sort(q+1,q+1+m,cmp);
        int l=1,r=0;
        fo(i,1,m)
        {
            while(l>q[i].l) Wadd(--l);
            while(l<q[i].l) Wdel(l++);
            while(r<q[i].r) Wadd(++r);
            while(r>q[i].r) Wdel(r--);
            ans[q[i].id]=anss;
        }
        fo(i,1,m) printf("%d\n",ans[i]);
        return Ratio;
    }
}
namespace Wistask3
{
    int qcnt=0,rcnt=0,ed[N],bl[N],ans[N],anss=0,mp[N];
    struct qry
    {
        int id,t,l,r;
        bool operator<(const qry &b)const
        {
            if(bl[l]==bl[b.l])
                if(bl[r]==bl[b.r]) return t<b.t;
                else return r<b.r;
            return l<b.l;
            //if(bl[l]!=bl[b.l]) return bl[l]<bl[b.l];
            //else if(bl[r]!=bl[b.r]) return bl[r]<bl[b.r];
            //else return t<b.t;
        }
    }qq[N];
    struct ope
    {
        int p,x;
    }rr[N];
    inline void Wadd(int x)
    {
        if(!mp[x]) anss++;
        mp[x]++;
    }
    inline void Wdel(int x)
    {
        mp[x]--;
        if(!mp[x]) anss--;
    }
	
    short main()
    {
        // fo(i,1,n) b[i]=a[i];
        sort(b+1,b+1+tot);
        tot=unique(b+1,b+1+tot)-b-1;
        fo(i,1,n) a[i]=lower_bound(b+1,b+1+tot,a[i])-b;
        int sq=pow(n,0.666);
        // fo(i,1,sq) ed[i]=n/sq*i;
        // ed[sq]=n;
        // fo(i,1,sq) fo(j,ed[i-1]+1,ed[i]) bl[j]=i;
        fo(i,1,n) bl[i]=i/sq+(i%sq!=0);
        fo(i,1,m)
        {
            if(q[i].op==2) qq[++qcnt]={qcnt,rcnt,q[i].l,q[i].r};
            else rr[++rcnt].p=q[i].l,rr[rcnt].x=lower_bound(b+1,b+1+tot,q[i].x)-b;
        }
        sort(qq+1,qq+1+qcnt);
        int l=1,r=0,las=0;
        fo(i,1,qcnt)
        {
            while(r<qq[i].r) Wadd(a[++r]);
            while(r>qq[i].r) Wdel(a[r--]);
            while(l>qq[i].l) Wadd(a[--l]);
            while(l<qq[i].l) Wdel(a[l++]);
            while(las<qq[i].t)
            {
                las++;
                if(rr[las].p>=l&&rr[las].p<=r) Wadd(rr[las].x),Wdel(a[rr[las].p]);
                swap(a[rr[las].p],rr[las].x);
            }
            while(las>qq[i].t)
            {
                if(rr[las].p>=l&&rr[las].p<=r) Wadd(rr[las].x),Wdel(a[rr[las].p]);
                swap(a[rr[las].p],rr[las].x);
                las--;
            }
            ans[qq[i].id]=anss;
        }
        fo(i,1,qcnt) printf("%d\n",ans[i]);
        return Ratio;
    }
}
namespace Wisadel
{
    short main()
    {
        // freopen(".in","r",stdin),freopen(".out","w",stdout);
        n=qr,m=qr;bool task2=1,task3=1;
        fo(i,1,n) b[i]=a[i]=qr;
		tot=n;
		// fuck
        if(n<=5000) return Wistask1::main();
        fo(i,1,m)
        {
            q[i].op=qr,q[i].l=qr,q[i].r=qr;
            q[i].id=i;
			// char ch;cin>>ch;
            // if(ch=='Q') q[i].op=2,q[i].l=qr,q[i].r=qr;
            // else q[i].op=1,q[i].l=q[i].r=qr,b[++tot]=q[i].x=qr;
            if(q[i].op==1)
            {
                b[++tot]=q[i].x=qr,task2=0;
                if(q[i].l!=q[i].r) task3=0;
            }
        }
        if(task2) return Wistask2::main();
        if(task3) return Wistask3::main();
        return Ratio;
    }
}
int main(){return Wisadel::main();}

还是挺爽的,毕竟 A 了两道。

不过要是打满的话就 Rank1 了不是吗。

但是确实很难打满,1h 做 T1,做完 T2 已经十点了。

关于 T4 改题
  • 怎么一直 RE?
    “不是它咋不给我出调试语句啊”
    “哦不对我编译错文件了”
  • 为啥输入一个字符导致 RE了?
    “诶我Windows跑没问题啊”
    “我重启下试试。。哦好了。。诶不对WA了。。诶不对编译错文件了。。。”
  • 这优化都一样怎么就 T 了?
    “诶分块这步怎么会差这么多时间”
    “我输出看看。。(输出了两种的分块结果)这咋两千多个块?哦这应该是块长。。”
穗限时返厂

豪堪捏


完结撒花~

你说得对

但我玩蓝图+益达的
image

标签:ch,return,int,tot,qr,ans,20,CSP,模拟
From: https://www.cnblogs.com/Ratio-Yinyue1007/p/18359783

相关文章

  • 考研数学模拟考试
         欧几里得8月模考正式开始报名了,走过路过千万不要错过,这是各位小伙伴检验复习成果、提升实力的大好机会哦,接下来是考试的一些信息:首先是所有小伙伴都会关心的一个问题,那就是考试收费吗?答案是考试全程免费,无隐性收费。参与模考、批改处分、直播解析等各个环节......
  • 2024版,一键安装永久激活!
    2024版,一键安装永久激活!https://mp.weixin.qq.com/s?__biz=MzkxMzEyNTA2Nw==&mid=2247504674&idx=1&sn=6402cfd91b92f85e28a282fe10216aea&chksm=c100e886f67761904f3eab4607504da67c7342d29cb6ae4374a9f9b4b459d237f1bee0095510&mpshare=1&scene=23&sr......
  • CSP/NOIP计数题一些奇奇怪怪的东西
    卡特兰数常见公式:不是很懂。\[H_n=C_{2n}^n-C_{2n}^{n-1}\]应用:折线计数。第二类斯特林数在小球与盒子那道模板题中见到的,表示表示将\(n\)个两两不同的元素,划分为\(k\)个互不区分的非空子集的方案数。递推式:\[\operatorname{S2}_{i,j}=j\times\operatorname{S2}_{i-......
  • 不同类型电动汽车充电负荷蒙特卡洛法模拟(常规充电、快速充电、更换电池)(Matlab代码实现
     ......
  • 暑期模拟赛题解
    暑期模拟赛题解CSP-J模拟赛2024.7.5CSP-J模拟赛1T1简单二分,判断即可。T2\(60pts\)的状压是好写的。至于\(100pts\),考虑dp状态的合并,由于\(m\)的级别很小,考虑对后\(m\)个数状压,考察满足条件的情况。dp难以优化的时候考察本质相同的状态。T3数据范围显......
  • D43 2-SAT+前缀优化 P6378 [PA2010] Riddle
    视频链接: P6378[PA2010]Riddle-洛谷|计算机科学教育新生态(luogu.com.cn)//2-SAT+前缀优化O(n+m)#include<iostream>#include<cstring>#include<algorithm>usingnamespacestd;#definex0(x)x//点#definex1(x)x+n//反点#definep0(x)x+2*n......
  • 河南萌新联赛2024第(五)场:信息工程大学
    河南萌新联赛2024第(五)场:信息工程大学前言有点水这场,原题和板子貌似有点多。。A-日历游戏_河南萌新联赛2024第(五)场:信息工程大学(nowcoder.com)思路首先不看年份的话,显然\(8/1\)败,\(7/31\)胜,\(7/30\)败,\(7/29\)胜,\(\dots\),以此类推,就能发现一个\((m+d)\bmod2=0\)\((m......
  • 联赛模拟!开创!
    由四个金牌命制的联赛模拟试卷,使我校高二高三竞赛班取得了一试最高84分,加试最高160分的好成绩!一试一、填空题如图是一个\(4\times4\)的正方形方格表,则最少需要\(\text{_____}\)条直线,才能使得每个方格都被至少一条直线穿过。设复数\(z\)满足:\(\frac{z-20}{\bar......
  • [考试记录] 2024.8.14 csp-s模拟赛20
    [考试记录]2024.8.13csp-s模拟赛2090+39+0+0还是太......
  • 【题解】【模拟】——帮贡排序
    【题解】【模拟】——帮贡排序帮贡排序题目背景题目描述输入格式输出格式输入输出样例输入#1输出#1提示1.题意解析1.1.结构体储存信息1.2.输入后调整职务的排序规则1.3.分配职务的方法1.4.职务的映射1.5.输出时的排序规则1.6.主函数2.代码帮贡排序题目背景在......