首页 > 其他分享 >多校A层冲刺NOIP2024模拟赛27终结篇

多校A层冲刺NOIP2024模拟赛27终结篇

时间:2024-11-28 20:12:14浏览次数:5  
标签:27 int 多校 mm en ans fi id NOIP2024

不知道是不是我打的最后一场模拟赛了,记录一下吧,总体来说还不错,虽然 \(T1\) 方案数求错爆零了,但 \(T3\) 场切了,暴力打满的话有265,希望 \(NOIP\) 时也可以不让自己遗憾吧。

A 【模板】分治FFT

考虑每加进来一个数的贡献 \(x_1*x_2+(x_1+x_2)*x_3+...=x_1*x_2+x_1*x_3+x_2*x_3+...\) 可以发现实际上不管怎么取都是每两个数相乘的和,所以直接一种方案的答案乘方案书即可,每次合并时少一堆,所以方案数是 $\sum \limits_{i=2}^{n} \dbinom{i}{2} $。

点击查看代码
#include<bits/stdc++.h>
#define int long long
const int mod=998244353;
const int maxn=1e5+10;
using namespace std;
int n,a[maxn],sum[maxn],ans,jc[maxn];

int qpow(int x,int y)
{
    int ans=1;
    while(y)
    {
        if(y&1) ans=ans*x%mod;
        x=x*x%mod;
        y>>=1;
    }
    return ans;
}

int c(int n,int m)
{
    return jc[n]*qpow(jc[m],mod-2)%mod*qpow(jc[n-m],mod-2)%mod;
}

signed main()
{
    freopen("fft.in","r",stdin);
    freopen("fft.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n;
    jc[0]=1;
    for(int i=1;i<=n;i++) jc[i]=jc[i-1]*i%mod;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=n;i>=1;i--) sum[i]=(sum[i+1]+a[i])%mod;
    for(int i=1;i<=n;i++) ans=(ans+a[i]*sum[i+1]%mod)%mod;
    int temp=c(n,2);
    for(int i=1;i<=n-2;i++) temp=temp*c(n-i,2)%mod;
    cout<<ans*temp%mod;;


    return 0;
}
/*
2
100001 100002
*/

B 【模板】最近公共祖先

构造,但是我没仔细推,我觉得题解说的很好,所以直接放了
image

点击查看代码
#include<bits/stdc++.h>
const int maxn=3e5+10;
using namespace std;
int n,m,cnt,dep[maxn];
int head[maxn],to[maxn<<1],nxt[maxn<<1],tot;
vector<int> s[maxn],t[maxn];
bool vis[maxn];
struct lsx
{
    int x,y,z;
}ans[maxn];
void add(int x,int y)
{
    to[++tot]=y;
    nxt[tot]=head[x];
    head[x]=tot;
}
void addm(int x,int y)
{
    add(x,y),add(y,x);
}

void lsx(int x)
{
    vis[x]=1;
    for(int i=head[x];i;i=nxt[i])
    {
        int y=to[i];
        if(vis[y])
        {
            if(dep[y]<dep[x]) s[x].push_back(y);
        }
        else dep[y]=dep[x]+1,lsx(y);
    }
    while(t[x].size()>1)
    {
        int p=t[x].back();t[x].pop_back();
        ans[++cnt]={p,x,t[x].back()};
        t[x].pop_back();
    }
    while(t[x].size()&&s[x].size())
    {
        ans[++cnt]={t[x].back(),x,s[x].back()};
        s[x].pop_back(),t[x].pop_back();
    }
    for(auto i:s[x]) t[i].push_back(x);
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1,x,y;i<=m;i++)
       cin>>x>>y,addm(x,y);
    for(int i=1;i<=n;i++) if(!vis[i]) lsx(i);
    cout<<cnt<<'\n';
    for(int i=1;i<=cnt;i++) cout<<ans[i].x<<" "<<ans[i].y<<" "<<ans[i].z<<'\n';

    return 0;
}
/*

*/

C 【模板】普通平衡树

关于我题解没看懂这件事,考虑新加进来一个数的贡献,由于保证了互不相同,所以新加进来一个数它要么使序列更长,要么就是替换掉最后一个数使值域差更大,每次更改只和最后两个数的值有关,直接对每个序列维护最后两个数的值和答案即可,暴力是 \(O(nq)\) 的,考虑线段树优化这个过程,两个序列段合并时发现,答案只和两个序列段边界的两个值的关系有关,所以线段树直接维护每个序列段最前面的两个数的值,最后面的两个数的值,序列长度,序列答案即可,合并的时候直接分讨边界四个数的大小关系即可,需要特判序列长度小于等于2时的情况。

点击查看代码
#include<bits/stdc++.h>
#define lid id<<1
#define rid id<<1|1
#define mid (l+r>>1)
const int maxn=3e5+10;
using namespace std;
int n,q;
struct lsx
{
    int fi[3],en[3],size,ans,lazy;
}m[maxn<<2],mm;

void add(int id,int x)
{
    if(!m[id].size)
    {
        m[id].size++;
        m[id].fi[1]=m[id].en[1]=x;
        m[id].ans=1;
    }
    else if(m[id].size==1)
    {
        m[id].size++;
        m[id].fi[2]=m[id].en[2]=x;
        m[id].ans=2;
    }
    else
    {
        if(m[id].en[1]>m[id].en[2])
        {
            if(x>m[id].en[2])
            {
                m[id].en[1]=m[id].en[2];
                m[id].en[2]=x;
                m[id].ans++;
            }
            else
            {
                if(m[id].size==2)m[id].fi[2]=x;
                m[id].en[2]=x;
            }
        }
        else
        {
            if(x<m[id].en[2])
            {
                m[id].en[1]=m[id].en[2];
                m[id].en[2]=x;
                m[id].ans++;
            }
            else
            {
                if(m[id].size==2)m[id].fi[2]=x;
                m[id].en[2]=x;
            }
        }
        m[id].size++;
    }
}

void solve(int x,int id)
{
    mm=m[x];
    if(mm.size==1)
    {
        add(id,mm.fi[1]);
        return ;
    }
    if(!m[id].size)
    {
        m[id].size=mm.size;
        m[id].fi[1]=mm.fi[1];
        m[id].fi[2]=mm.fi[2];
        m[id].en[1]=mm.en[1];
        m[id].en[2]=mm.en[2];
        m[id].ans=mm.ans;
    }
    else if(m[id].size==1)
    {
        if(mm.fi[1]<mm.fi[2])
        {
            if(m[id].fi[1]<mm.fi[1])
            {
                mm.fi[1]=m[id].fi[1];
                m[id].size=mm.size;
                m[id].fi[1]=mm.fi[1];
                m[id].fi[2]=mm.fi[2];
                m[id].en[1]=mm.en[1];
                m[id].en[2]=mm.en[2];
                m[id].ans=mm.ans;
            }
            else
            {
                mm.size++,mm.ans++;
                mm.fi[2]=mm.fi[1];
                mm.fi[1]=m[id].fi[1];
                m[id].size=mm.size;
                m[id].fi[1]=mm.fi[1];
                m[id].fi[2]=mm.fi[2];
                m[id].en[1]=mm.en[1];
                m[id].en[2]=mm.en[2];
                m[id].ans=mm.ans;
            }
        }
        else
        {
            if(m[id].fi[1]>mm.fi[1])
            {
                mm.fi[1]=m[id].fi[1];
                m[id].size=mm.size;
                m[id].fi[1]=mm.fi[1];
                m[id].fi[2]=mm.fi[2];
                m[id].en[1]=mm.en[1];
                m[id].en[2]=mm.en[2];
                m[id].ans=mm.ans;
            }
            else
            {
                mm.size++,mm.ans++;
                mm.fi[2]=mm.fi[1];
                mm.fi[1]=m[id].fi[1];
                m[id].size=mm.size;
                m[id].fi[1]=mm.fi[1];
                m[id].fi[2]=mm.fi[2];
                m[id].en[1]=mm.en[1];
                m[id].en[2]=mm.en[2];
                m[id].ans=mm.ans;
            }
        }
    }
    else
    {
        if(m[id].en[1]>m[id].en[2])
        {
            if(mm.fi[1]<mm.fi[2])
            {
                if(mm.size==2) mm.en[1]=min(mm.en[1],m[id].en[2]);
                m[id].size+=mm.size-1;
                m[id].ans+=mm.ans-1;
                m[id].en[1]=mm.en[1],m[id].en[2]=mm.en[2];
            }
            else
            {
                if(m[id].en[2]<mm.fi[1])
                {
                    m[id].size+=mm.size;
                    m[id].ans+=mm.ans;
                    m[id].en[1]=mm.en[1],m[id].en[2]=mm.en[2];
                }
                else
                {
                    if(mm.size==2) mm.en[1]=m[id].en[1];
                    m[id].size+=mm.size-2;
                    m[id].ans+=mm.ans-2;
                    m[id].en[1]=mm.en[1],m[id].en[2]=mm.en[2];
                }
            }
        }
        else
        {
            if(mm.fi[1]>mm.fi[2])
            {
                if(mm.size==2) mm.en[1]=max(mm.en[1],m[id].en[2]);
                m[id].size+=mm.size-1;
                m[id].ans+=mm.ans-1;
                m[id].en[1]=mm.en[1],m[id].en[2]=mm.en[2];
            }
            else
            {
                if(m[id].en[2]>mm.fi[1])
                {
                    m[id].size+=mm.size;
                    m[id].ans+=mm.ans;
                    m[id].en[1]=mm.en[1],m[id].en[2]=mm.en[2];
                }
                else
                {
                    if(mm.size==2) mm.en[1]=m[id].en[1];
                    m[id].size+=mm.size-2;
                    m[id].ans+=mm.ans-2;
                    m[id].en[1]=mm.en[1],m[id].en[2]=mm.en[2];
                }
            }
        }
    }
}

void down(int id)
{
    if(!m[id].lazy) return ;
    solve(id,lid);
    solve(id,rid);
    m[lid].lazy=m[rid].lazy=1;
    m[id].lazy=m[id].size=m[id].ans=m[id].fi[1]=m[id].fi[2]=m[id].en[1]=m[id].en[2]=0;
}

void update(int id,int l,int r,int s,int t,int x)
{
    if(l>=s&&r<=t)
    {
        m[id].lazy=1;
        add(id,x);
        return ;
    }
    down(id);
    if(mid>=s) update(lid,l,mid,s,t,x);
    if(mid<t) update(rid,mid+1,r,s,t,x);
}

int query(int id,int l,int r,int x)
{
    // cout<<l<<" "<<r<<" "<<x<<endl;
    if(l==r) return m[id].ans;
    down(id);
    return x<=mid?query(lid,l,mid,x):query(rid,mid+1,r,x);
}

int main()
{
    freopen("odt.in","r",stdin);
    freopen("odt.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>q;
    while(q--)
    {
        int op,l,r,x;
        cin>>op;
        if(op==1)
        {
            cin>>l>>r>>x;
            update(1,1,n,l,r,x);
        }
        else
        {
            cin>>x;
            cout<<query(1,1,n,x)<<'\n';
        }
    }


    return 0;
}
/*
10 4
1 6 6 697
1 4 8 824
1 6 7 455
2 7

*/

标签:27,int,多校,mm,en,ans,fi,id,NOIP2024
From: https://www.cnblogs.com/oceansofstars/p/18575072

相关文章

  • 多校A层冲刺NOIP2024模拟赛27终结篇
    多校A层冲刺NOIP2024模拟赛27终结篇前言就一定要让我挂分吗???T1证出结论后却交了一发错解,成功挂100。T2是不是可以直接贪,直接写。T2写完了,tm怎么也没有大样例?T3是不是可以线段树。T3是不是不可以线段树。T4是不是可以K-DTree,但我不会写K-DTree。T4是不是可以......
  • NOIP2024 前集训:多校A层冲刺NOIP2024模拟赛 27 终结篇
    前言点击查看代码《蜂鸟》传说中人类在远早住于黑暗的地下之遥派出了娇小的蜂鸟找到通往光明的隧道飞过了一座一座岛好想有一个地方落脚把一个一个梦制造会不会有人能够听到寻找太阳的梦自不量力说自己也变成太阳的念头有时候寂寞几乎扛不动咽在喉咙......
  • 多校A层冲刺NOIP2024模拟赛27终结篇
    多校A层冲刺NOIP2024模拟赛27终结篇\(T1\)A.【模板】分治FFT\(0pts\)将式子展开后是一个形如\(f_{n}\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{i-1}a_{i,j}\)的形式。考虑\(f_{n}\)如何转移。当我们选出一对\((i,j)\)进行合并进入\(n'=n-1\)的子问题,故\(a_{i}......
  • noip2024 复习计划
    大致分三步:基本模板、套路复习套题复盘再刷一两道码力题基本模板复习有(参照csp2024套题复盘表):1.数据结构平衡树线段树、树状数组的Trick2.杂算法CDQ分治、整体二分、点分治、点分树KMP(其实不用复习了)3.图论Dijkstra板子,以及最小生成树......
  • 『模拟赛』多校A层冲刺NOIP2024模拟赛27终结篇
    Rankrp++A.【模板】分治FFT签。没取模挂50pts。列出式子发现无论何种合并方式,最终权值均为\(\sum_{i=1}^n\a_i\times(\sum_{j=i}^n\a_i)\),因此求方案数即可。发现每一步相当于从当前堆数中任选两个出来,容易得出方案数为\(\prod_{i=2}^{n}\binom{i}{2}\)。时间复杂度......
  • [赛记] NOIP2024加赛8
    大抵是NOIP前写的最后一篇题解了吧。。。flandre80pts赛时打的错解A了,然后证伪以后写了个更错的错解80pts;考虑我们最终要求的答案是$a$数组从小到大排序后的一个后缀;考虑怎样证明这个结论,感性理解一下就是尽量选大的然后挺对;考虑比较严谨的证明;如果序列中没有重复的......
  • 每日一题Online Judge(OJ)1273 哥德巴赫猜想的所有解
    OKnow每日一题来了哦 今天题目是OnlineJudge(OJ)编号为1273的哥德巴赫猜想的所有解现在让我们一起来seesee题目以下为哥德巴赫猜想简介(1742年6月7日哥德巴赫写信给当时的大数学家欧拉,正式提出了以下的猜想:任何一个大于9的奇数都可以表示成3个质数之和。质数是指除......
  • 左侧导航栏element -2024/11/27
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>首页</title><style>.demo-table-expand{font-size:0;}.demo-table-expand......
  • 2024.11.27
    您遇到的org.mybatis.spring.MyBatisSystemException:nestedexceptionisorg.apache.ibatis.binding.BindingException:Parameter'taskId'notfound.Availableparametersare[arg1,arg0,param1,param2]错误通常是由于MyBatis在执行SQL语句时无法找到对应的参数......
  • Java学习笔记——2024.11.27
    2024.11.27一、字符类型1.字符类型初探可以存放一个汉字(2字节)或者数字(这个c4存储的应该是ASCII编码为97的字符,也就是a)2.字符类型细节publicclassChardetial{publicstaticvoidmain(String[]args){charc1=97;System.out.println(c1)......