首页 > 其他分享 >多校A层冲刺NOIP2024模拟赛24

多校A层冲刺NOIP2024模拟赛24

时间:2024-11-19 21:19:01浏览次数:1  
标签:24 sta int rep 多校 long using NOIP2024 mod

选取字符串

建出失配树以后直接dp就好了。但场上现推的kmp……

点此查看代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,s,t,p) for(int i = s;i <= t; i += p)
#define drep(i,s,t,p) for(int i = s;i >= t; i -= p)
#ifdef LOCAL
    FILE *InFile = freopen("in.in","r",stdin),*OutFile = freopen("out.out","w",stdout);
#else
    FILE *InFile = freopen("string.in","r",stdin),*OutFile = freopen("string.out","w",stdout);
    // FILE *InFile = stdin,*OutFile = stdout;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
#define int long long
const int N = 1e6 + 10,mod = 998244353;
int n,k,fac[N<<2],inv[N<<2],sum[N],nxt[N],ct[N],dep[N],siz[N],ans = 0;
char s[N];
inline int power(int a,int b,int mod){
    int res = 1;
    for(;b;b >>= 1,a = 1ll*a*a%mod)
        if(b&1) res = 1ll*res*a%mod;
    return res;
}
inline int Inv(int a){return power(a,mod-2,mod);}
inline int C(int n,int m){
    if(m > n) return 0;
    return 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod;
}
vector<int> son[N];
void dfs(int x){
    dep[x] = dep[nxt[x]] + 1;
    siz[x] = 1;
    for(auto y:son[x]){
        dfs(y);
        siz[x] += siz[y];
        ct[x] = (ct[x] - C(siz[y],k) + mod)%mod;
    }
    ct[x] = (ct[x] + C(siz[x],k))%mod;
    ans = (ans + 1ll*ct[x]*dep[x]%mod*dep[x]%mod)%mod;
}
inline void solve(){
    cin>>k>>(s+1);n = strlen(s+1);
    n<<=2;
    fac[0] = 1;rep(i,1,n,1) fac[i] = 1ll*fac[i-1]*i%mod;
    inv[n] = Inv(fac[n]);drep(i,n-1,0,1) inv[i] = 1ll*inv[i+1]*(i+1)%mod;
    n>>=2;
    int j = 0;
    son[0].emplace_back(1);
    rep(i,2,n,1){
        while(j && s[i] != s[j+1]) j = nxt[j];
        j += (s[i] == s[j+1]);
        nxt[i] = j;son[nxt[i]].emplace_back(i);
    }
    dfs(0);
    cout<<ans;
}
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    solve();
}

取石子

打表找规律发现当且仅当\(lowbit(\oplus_ia_i)\le k\)时先手必胜。

然后发现每次增加的一定为\(2^k\)且不降,直接暴力枚举即可,时间复杂度\(O(n\log V)\)。

点此查看代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,s,t,p) for(int i = s;i <= t; i += p)
#define drep(i,s,t,p) for(int i = s;i >= t; i -= p)
#ifdef LOCAL
    FILE *InFile = freopen("in.in","r",stdin),*OutFile = freopen("out.out","w",stdout);
#else
    // FILE *InFile = stdin,*OutFile = stdout;
    FILE *InFile = freopen("nim.in","r",stdin),*OutFile = freopen("nim.out","w",stdout);
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
#define int long long
const int N = 5e4 + 10;
int n,k,a[N];
bool f[50],flag,cp[50];
inline void solve(){
    cin>>n>>k;rep(i,1,n,1) cin>>a[i];
    int lgk = __lg(k);
    rep(i,0,lgk,1){rep(j,1,n,1) f[i]^=(a[j]>>i)&1;flag |= f[i];}
    if(!flag) cout<<"0\n";
    else{
        cout<<"1\n";
        rep(i,1,n,1){
            rep(j,0,lgk,1) cp[j] = f[j];
            int sum = 0;
            rep(j,0,__lg(a[i]),1){
                if(!cp[j]) continue;
                sum |= 1<<j;
                if(sum > k) break;
                cout<<i<<' '<<sum<<'\n';
                rep(l,j,lgk,1) cp[l] ^= a[i]>>l&1;
                a[i] -= 1<<j;
                rep(l,j,lgk,1) cp[l] ^= a[i]>>l&1;
            }
        }
    }
}
signed main(){cin.tie(nullptr)->sync_with_stdio(false);solve();}

均衡区间

记\(ml_{i},sl_{i},mr_{i},sr_{i}\)分别表示左边第一个比\(a_i\)大的数的位置,左边第一个比\(a_i\)小的数的位置,右边第一个比\(a_i\)大的数的位置,右边第一个比\(a_i\)小的数的位置。记\(L_{i}=\min\{ml_{i},sl_{i}\}\)

假如\([i,j]\)是一个合法区间,那么有\(i<L_{j}\And R_{i}<j\),二维数点。正反求两遍就好了。

点此查看代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,s,t,p) for(int i = s;i <= t; i += p)
#define drep(i,s,t,p) for(int i = s;i >= t; i -= p)
#ifdef LOCAL
    FILE *InFile = freopen("in.in","r",stdin),*OutFile = freopen("out.out","w",stdout);
#else
    // FILE *InFile = stdin,*OutFile = stdout;
    FILE *InFile = freopen("interval.in","r",stdin),*OutFile = freopen("interval.out","w",stdout);
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
const int N = 1e6 + 10;
int n,a[N],ans1[N],ans2[N],id;
int mr[N],ml[N],sr[N],sl[N],L[N],R[N];
struct BIT{
    int mx,tree[N];
    inline void init(int n){mx = n;memset(tree,0,sizeof tree);}
    inline int lb(int x){return (x&(-x));}
    inline void upd(int pos,int val){rep(i,pos,mx,lb(i)) tree[i] += val;}
    inline int qry(int pos){int res = 0;drep(i,pos,1,lb(i)) res += tree[i];return res;}
}T;
stack<int> sta;
inline void get(int *ans){
    drep(i,n,1,1){while(sta.size() && a[sta.top()] < a[i]) ml[sta.top()] = i,sta.pop();sta.push(i);}
    while(sta.size()) ml[sta.top()] = 1,sta.pop();
    drep(i,n,1,1){while(sta.size() && a[sta.top()] > a[i]) sl[sta.top()] = i,sta.pop();sta.push(i);}
    while(sta.size()) sl[sta.top()] = 1,sta.pop();
    rep(i,1,n,1){while(sta.size() && a[sta.top()] < a[i]) mr[sta.top()] = i,sta.pop();sta.push(i);}
    while(sta.size()) mr[sta.top()] = n,sta.pop();
    rep(i,1,n,1){while(sta.size() && a[sta.top()] > a[i]) sr[sta.top()] = i,sta.pop();sta.push(i);}
    while(sta.size()) sr[sta.top()] = n,sta.pop();
    rep(i,1,n,1) L[i] = min(ml[i],sl[i]),R[i] = max(mr[i],sr[i]);
    T.init(n);vector<pair<int,int> > vec;
    rep(i,1,n,1) vec.emplace_back(L[i],i);
    sort(vec.begin(),vec.end(),greater<pair<int,int> >());
    int now = -1;
    drep(i,n,1,1){
        while(now < n-1 && vec[now+1].first > i){now++;T.upd(vec[now].second,1);}
        ans[i] = T.qry(T.mx)-T.qry(R[i]);
    }
}
inline void solve(){
    cin>>n>>id;rep(i,1,n,1) cin>>a[i];
    get(ans1);
    rep(i,1,n,1) cout<<ans1[i]<<' ';cout<<'\n';
    reverse(a+1,a+1+n);get(ans2);
    reverse(ans2+1,ans2+1+n);
    rep(i,1,n,1) cout<<ans2[i]<<' ';
}
signed main(){cin.tie(nullptr)->sync_with_stdio(false);solve();}

禁止套娃

不会。

p

image

标签:24,sta,int,rep,多校,long,using,NOIP2024,mod
From: https://www.cnblogs.com/hzoi-Cu/p/18555617

相关文章

  • 241119 noip 模拟赛
    省流:\(100+50+45+32\)。rk8,喜提前十名中唯一没过t2的。T1题意:对于一棵树,记\(f(i)\)表示\(\sum_{1\leqj\leqn}dis(i,j)\),其中\(dis(i,j)\)表示树上\(i,j\)之间的距离。多测,每次给定一个\(x\),你需要找出最小的一个\(n\),使得存在一个\(n\)个点的树,其上存在......
  • NOIP2024加赛6
    一签三计数,罚坐了。草莓简单贪心,随便贪就过了。点此查看代码#include<bits/stdc++.h>usingnamespacestd;#definerep(i,s,t,p)for(inti=s;i<=t;i+=p)#definedrep(i,s,t,p)for(inti=s;i>=t;i-=p)#ifdefLOCAL FILE*InFile=freopen("in.in","r......
  • 2024.11.19 test
    A给定一个无限长序列的\(0\simn-1\)项,每项满足与\(n\)的差不超过\(1\)。之后的每一项满足\(a_i=\sum_{j=0}^{i-1}[a_j+j\gei]\)。\(q\)次询问第\(p\)个位置的值。\(p\le10^{15}\)。非常难的签到,考虑消去常数,将\(a_i\)全部减去\(n\),那么\(a_i=[a_{i-n-1}=1]-[a_......
  • 网鼎杯 2024 玄武 pwn2 (kernel)
    setup准备工作voidunshare_setup(){charedit[0x100];inttmp_fd;//fromlibpthreadunshare(CLONE_NEWNS|CLONE_NEWUSER|CLONE_NEWNET);//fromlibfcntltmp_fd=open("/proc/self/setgroups",O_WRONLY);write(tmp_f......
  • 2024/11/19日 日志 数据结构实验(2)---栈实现表达式求值、队列应用(蓝桥杯)
    栈实现表达式求值问题:https://pintia.cn/problem-sets/1858366427985383424/exam/problems/type/7?problemSetProblemId=1858366732315615232解答:点击查看代码#include<bits/stdc++.h>usingnamespacestd;//运算符优先级intprecedence(charop){switch(op){......
  • 2024/11/18日 日志 数据结构实验(1)---链表逆置、线性表A,B顺序存储合并、双向循环链表应
    链表逆置题目:https://pintia.cn/problem-sets/1855808612225744896/exam/problems/type/6?problemSetProblemId=1855808768018968576解答:点击查看代码structListNode*reverse(structListNode*head){structListNode*prev=NULL;structListNode*current=head;......
  • 「模拟赛」多校 A 层冲刺 NOIP 24
    A.选取字符串KMP、字符串好题因为所有字符串都是大字符串的前缀,所以一旦我们每个字符串的前缀后缀的长度确定了,那么前缀后缀长什么样也就确定了设\(f_i\)为所有相同前缀后缀长度可以为\(i\)的字符串的个数我们枚举\(i\in[1,n]\),每次钦定两个串\(p、q\)里必须有一个是......
  • 724. 寻找数组的中心下标
    题目自己写的classSolution{public:intpivotIndex(vector<int>&nums){intn=nums.size();vector<int>s(n,0);s[0]=nums[0];for(inti=1;i!=n;++i)s[i]=s[i-1]+nums[i];......
  • 20222408 2024-2025-1 《网络与系统攻防技术》实验五实验报告
    1.实验内容1.1实验要求(1)选择一个DNS域名进行查询,获取如下信息:DNS注册人及联系方式、该域名对应IP地址、IP地址注册人及联系方式、IP地址所在国家、城市和具体地理位置。(2)尝试获取QQ中某一好友的IP地址,并查询获取该好友所在的具体地理位置。(3)使用nmap开源软件对靶机环境进行扫......
  • 24. 两两交换链表中的节点
    https://leetcode.cn/problems/swap-nodes-in-pairs/?envType=study-plan-v2&envId=top-100-liked对于我们正常交换单向链表的两个节点我们需要知道三个节点的信息,1.对于a->b->c,我们要交换a、b就要知道a、b、c三个节点,因为我们需要将a的next指向c,将b的next指向a,由于b->c这条......