多校A层冲刺NOIP2024模拟赛04

news/2024/10/9 19:00:21/文章来源:https://www.cnblogs.com/hzoi-Cu/p/18454912

多校A层冲刺NOIP2024模拟赛04

学校OJ赛时 rank28,T1 0pts,T2 100pts,T3 20pts,T4 25pts
accoders rank15,T1 100pts,T2 100pts,T3 20pts,T4 25pts

不是,也没人告诉我两个OJ文件名不一样啊

02表示法

递归 + 高精除低精。

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
#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 LOCALFILE *InFile = infile("in.in"),*OutFile = outfile("out.out");FILE *ErrFile=errfile("err.err");
#elseFILE *Infile = infile("power.in"),*OutFile = outfile("power.out");//FILE *ErrFile = stderr;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
const int N = 200;
string s;
ll n;
inline int divide(string &s){if(!s.size()) return -1;if(s.size() == 1 && s[0] == '0') return -1;if(s.size() == 1 && s[0] == '1'){s = "";return 1;}int res = (s.back() - '0')%2;s.back() -= res;int n = s.size(),x = 0;string sh;bool flag = false;rep(i,0,n-1,1){x = x*10 + (s[i] - '0');if(x >= 2) sh.push_back(x/2+'0'),x %= 2,flag = true;else if(flag) sh.push_back('0');}s = sh;return res;
}
#define pii pair<int,int>
#define mk make_pair
void work(string s){if(s == "0") return cout<<0,void();if(s == "1") return cout<<"1",void();if(s == "2") return cout<<"2",void();if(!s.size()) return;vector<pii> p;rep(i,0,999999,1){int x = divide(s);if(x == -1) break;if(!x) continue;p.emplace_back(mk(i,1));}reverse(p.begin(),p.end());int len = p.size();for(int i = 0;i < len; ++i){if(p[i].first == 1) {cout<<2;goto ed;}cout<<2;if(p[i].first != 1) cout<<'(';work(to_string(p[i].first));if(p[i].first != 1) cout<<')';ed:;if(i != len - 1) cout<<'+';}
}
inline void solve(){cin>>s;work(s);
}
signed main(){cin.tie(nullptr)->sync_with_stdio(false);cout.tie(nullptr)->sync_with_stdio(false);solve();
}

子串的子串

赛时写了一个\(O(nq\log n)\)的暴力,本来是能拿70pts的,但是常数小+信仰就过了。

就是把每次查询的串截出来,然后跑个后缀数组求\(height\),用结论 : 一个字符串本质不同的子串的数量为\(\frac{n\times (n+1)}{2}-\sum_{i=2}^n height_i\),就可以了。

求后缀数组用的倍增法,用\(DC3\)的话就是\(O(nq)\)

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
#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 LOCALFILE *InFile = infile("in.in"),*OutFile = outfile("out.out");// FILE *ErrFile=errfile("err.err");
#elseFILE *Infile = infile("substring.in"),*OutFile = outfile("substring.out");//FILE *ErrFile = stderr;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
const int N = 3010;
char *p1,*p2,buf[1<<23];
#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<23,stdin),p1==p2)?EOF:*p1++)
#ifdef linux
#define pc putchar_unlocked
#else
#define pc putchar
#endif
namespace IO{template<typename T>inline bool read(T &x){x=0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x<<1)+(x<<3)+(s^48);if(!f) x=~x+1;return true;}inline bool read(double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}inline bool read(long double &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}inline bool read(float &x){x=0.0;char s=gc();bool f=true;for(;(s<'0'||'9'<s);s=gc()) {if(s=='-') f=false;if(s==EOF)return false;}for(;'0'<=s&&s<='9';s=gc()) x=(x*10)+(s^48);if(s!='.'){return true;}double res=0.1;s=gc();for(;'0'<=s&&s<='9';res/=10,s=gc()) x+=(s^48)*res;x=f?x:-x;return true;}inline bool read(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false; for(;s!=' '&&s!='\n'&&s!=EOF;s=gc())str.push_back(s);return true;}inline bool read_line(string &str){string ().swap(str);char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str.push_back(s);}return true;}inline bool read_line(char *str){int len=0;char s=gc();for(;s==' '||s=='\n';s=gc());if(s==EOF) return false;for(;s!='\n'&&s!=EOF;s=gc()){str[len]=s;len++;}str[len]='\0';return true;}inline bool read(char &s){char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF||x==' '||x=='\n')return false;s=x;return true;}inline bool read(char *s){int len=0;char x=gc();for(;x==' '||x=='\n';x=gc());if(x==EOF)return false;for(;x!=' '&&x!='\n'&&x!=EOF;x=gc())s[len++]=x;s[len]='\0';return true;}template<class T,class... Args> inline bool read(T &x,Args&... args){return (read(x)&&read(args...));}template<class T>inline void write(T x){static T st[45];int top=0;if(x<0)x=~x+1,pc('-');do{st[top++]=x%10;}while(x/=10);while(top)pc(st[--top]^48);}inline void write(char x){pc(x);}inline void write(string s){for(int i=0;s[i];++i) pc(s[i]);}inline void write(char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}inline void write(const char *s){int len=strlen(s);for(int i=0;i<len;++i) pc(s[i]);}template<class T,class... Args> inline void write(T x,Args... args){write(x);write(args...);}
}using namespace IO;
int n,m,sa[N],rk[N],tp[N],ht[N],ct[N];char s[N],s1[N];
inline void Qsort(int m){rep(i,1,m,1) ct[i] = 0;rep(i,1,n,1) ++ct[rk[i]];rep(i,2,m,1) ct[i] += ct[i-1];drep(i,n,1,1) sa[ct[rk[tp[i]]]--] = tp[i];
}
inline bool cmp(int x,int y,int w){return (tp[x]==tp[y]&&tp[x+w]==tp[y+w]);}
inline void get_sa(){n = strlen(s+1);int m = 27;rep(i,1,n,1) rk[i] = s[i] - 'a' + 1,tp[i] = i;Qsort(m);for(int w=1,p=0;w<=n;m=p,p=0,w<<=1){rep(i,n-w+1,n,1) tp[++p]=i;rep(i,1,n,1) if(sa[i]>w) tp[++p]=sa[i]-w;Qsort(m);rep(i,1,n,1) swap(tp[i],rk[i]);p=rk[sa[1]]=1;rep(i,2,n,1) rk[sa[i]]=cmp(sa[i-1],sa[i],w)?p:++p;if(p==n) break;}int k = 0;rep(i,1,n,1){if(!rk[i]) continue;if(k) --k;while(s[i+k] == s[sa[rk[i]-1]+k]) k++;ht[rk[i]] = k;}
}
inline void solve(){read(n,m);read(s1+1);while(m--){int l,r;ll ans;read(l,r);rep(i,l,r,1) s[i-l+1] = s1[i];n = r-l+1;s[n+1] = '\0';get_sa();ans = 1ll*n*(n+1)/2;rep(i,2,n,1) ans -= ht[i];rep(i,1,n,1) ht[i] = rk[i] = sa[i] = tp[i] = 0;write(ans,'\n');}
}
signed main(){solve();
}

正解是预处理,二维前缀和。

\(ans_{l,r}\)表示区间\([l,r]\)及其子区间本质不同的字符串的个数。可以先维护差分数组然后前缀和解决。

先枚举子串长度,再枚举左端点,通过预处理的前缀和求出这\([l,r]\)一子串的哈希值,那么该串的左右端
\([l,r]\)的答案加一,即\(ans_{l,r}++\),为了避免重复统计,该串还在上次该串出现位置到该位置
之间该串都有贡献,那么应该将上一次出现的左端点\(pre\)(字符串哈希维护)与当前右端点的答案减一,
\(ans_{pre,r}--\),最后对数组求和得到的其实是会有重复贡献,要通过容斥计算出每个区间的答案\(ans_{l,r}\)
,回答询问

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
#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 LOCALFILE *InFile = infile("in.in"),*OutFile = outfile("out.out");// FILE *ErrFile=errfile("err.err");
#elseFILE *Infile = infile("substring.in"),*OutFile = outfile("substring.out");//FILE *ErrFile = stderr;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
const int N = 3010;
char s[N];
int n,m,ans[N][N];
ull hs[N],pw[N],base = 131;
inline ull get_hash(int l,int r){return hs[r] - hs[l-1]*pw[r-l+1];}
inline void solve(){cin>>n>>m>>(s+1);pw[0] = 1;rep(i,1,n,1) pw[i] = pw[i - 1] * base;rep(i,1,n,1) hs[i] = hs[i-1]*base + s[i];rep(len,1,n,1){__gnu_pbds::gp_hash_table<ull,int> mp;rep(l,1,n-len+1,1){int r = l + len - 1;ull h = get_hash(l,r);ans[mp[h]][r]--;mp[h] = l;}}drep(l,n,1,1) rep(r,l,n,1)ans[l][r] += ans[l + 1][r] + ans[l][r - 1] - ans[l+1][r-1] + 1;while(m--){int l,r;cin>>l>>r;cout<<ans[l][r]<<'\n';}
}
signed main(){cin.tie(nullptr)->sync_with_stdio(false);cout.tie(nullptr)->sync_with_stdio(false);solve();
}

魔法咒语

考虑一个串是被两个拼起来的或者就一个,一个的特判掉。

考虑对于每一个前缀扩展,假设拓展的第一个字符为\(c\)

加入\(c\)已经被扩展过了,那么看看它是否是最后一个节点,如果是,那么说明这个咒语本身就存在,直接加上一个即可。

反之,那么就考虑所有第一个字符为\(c\)的不同后缀都可以。

前缀的话插入一个正向的Trie就可以,看后缀的话插入一个后缀的Trie即可。

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
#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 LOCALFILE *InFile = infile("in.in"),*OutFile = outfile("out.out");// FILE *ErrFile=errfile("err.err");
#elseFILE *Infile = infile("magic.in"),*OutFile = outfile("magic.out");//FILE *ErrFile = stderr;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
const int N = 4e5 + 10;
struct Trie{int tree[N][27],cnt[N],tot;inline void insert(string s,bool rev){int p = 0,len = s.size()-1;if(rev) reverse(s.begin(),s.end());rep(i,0,len,1){int x = s[i] - 'a' + 1;if(!tree[p][x]) tree[p][x] = ++tot,cnt[x] += rev;p = tree[p][x];}}
}t1,t2;
ll ans = 0,n;
string s[N];
bitset<27> ok,flag;
inline void solve(){cin>>n;rep(i,1,n,1){cin>>s[i];t1.insert(s[i],false);t2.insert(s[i],true);int len = s[i].size();ok[s[i].back() - 'a' + 1] = true;if(len == 1 && !flag[s[i][0] - 'a' + 1]) ans++,flag[s[i][0] - 'a' + 1] = true;}rep(i,1,t1.tot,1) rep(j,1,26,1)if(!t1.tree[i][j]) ans += t2.cnt[j];else if(ok[j]) ans++;cout<<ans<<'\n';
}
signed main(){cin.tie(nullptr)->sync_with_stdio(false);cout.tie(nullptr)->sync_with_stdio(false);solve();
}

表达式

线段树。不太懂啊。

将给的模数分解成\(\prod p_i^{k_i}\),然后以每个\(p_i^{k_i}\)为模数,求出答案以后再用CRT合并。

至于以\(p_i^{k_i}\)为模数的处理,用线段树暴力记录就好了。

点此查看代码
#include<bits/stdc++.h>
#include<bits/extc++.h>
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;
using namespace std;
#define infile(x) freopen(x,"r",stdin)
#define outfile(x) freopen(x,"w",stdout)
#define errfile(x) freopen(x,"w",stderr)
#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 LOCALFILE *InFile = infile("in.in"),*OutFile = outfile("out.out");// FILE *ErrFile=errfile("err.err");
#elseFILE *Infile = infile("expr.in"),*OutFile = outfile("expr.out");//FILE *ErrFile = stderr;
#endif
using ll=long long;using ull=unsigned long long;
using db = double;using ldb = long double;
#define fi first
#define se second
#define pii pair<char,int>
#define mk make_pair
const int N = 2e5 + 10;
int n,m,mod;
pii a[N];struct Segment_Tree{struct segment_tree{int l,r,val[30];#define l(k) tree[k].l#define r(k) tree[k].r#define val(k) tree[k].val}tree[N<<2];int p;unordered_map<char,function<int(int,int)> > op = {{'+',[&](int a,int b){return (a+b)%p;}},{'*',[&](int a,int b){return 1ll*a*b%p;}},{'^',[&](int a,int b){int res = 1;for(;b;b >>= 1,a = 1ll*a*a%p) if(b&1) res = 1ll*res*a%p;return res;}}};inline void pushup(int k){rep(i,0,p-1,1) val(k)[i] = val(k<<1|1)[val(k<<1)[i]];}void build(int k,int l = 1,int r = n){l(k) = l,r(k) = r;if(l == r){rep(i,0,p-1,1) val(k)[i] = op[a[l].fi](i,a[l].se);return;}int mid = (l + r) >> 1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);pushup(k);}void change(int k,int pos){if(l(k) == r(k)){rep(i,0,p-1,1) val(k)[i] = op[a[pos].fi](i,a[pos].se);return;}int mid = (l(k) + r(k)) >> 1;if(pos <= mid) change(k<<1,pos);else change(k<<1|1,pos);pushup(k);}
}T[4];
int exgcd(int a,int b,int &x,int &y){if(!b) return x = 1,y = 0,a;int d = exgcd(b,a%b,x,y);int t = x;x = y;y = t - (a/b)*y;return d;
}
namespace TP{const int N = 2e5 + 10;char op[N];int testid,n,m,mod,a[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 void solve(){cin>>n>>m>>mod;rep(i,1,n,1) cin>>op[i]>>a[i];while(m--){int p,x;cin>>p;if(p == 1){cin>>x;rep(i,1,n,1){if(op[i] == '+') x = (0ll+x+a[i])%mod;if(op[i] == '*') x = 1ll*x*a[i]%mod;if(op[i] == '^') x = power(x,a[i],mod);}cout<<x<<'\n';}else{char c;int y;cin>>x>>c>>y;op[x] = c,a[x] = y;}}}
}
inline void solve(){int id;cin>>id;if(id <= 3){TP::solve();return;}cin>>n>>m>>mod;rep(i,1,n,1) cin>>a[i].fi>>a[i].se;vector<int> d;int res = mod;for(int i = 2;i * i <= res; ++i){if(res % i == 0){int k = 1;while(res % i == 0) res /= i,k *= i;d.emplace_back(k);}}if(res > 1) d.emplace_back(res);for(int i = 0;i < d.size(); ++i){T[i].p = d[i],T[i].build(1);}// exit(0);auto get_ans = [&](vector<int> &v){int res = 0;for(int i = 0;i < v.size(); ++i){int m = mod/d[i],b,y;exgcd(m,d[i],b,y);res = (res + 1ll * v[i] * m % mod * b % mod) % mod;}return (res + mod) % mod;};while(m--){int op;cin>>op;if(op == 1){int x;cin>>x;vector<int> v;for(int i = 0;i < d.size(); ++i) v.emplace_back(T[i].tree[1].val[x%T[i].p]);cout<<get_ans(v)<<'\n';}else{int x,z;cin>>x;char y;cin>>y>>z;a[x] = mk(y,z);for(int i = 0;i < d.size();T[i++].change(1,x));}}}
signed main(){cin.tie(nullptr)->sync_with_stdio(false);cout.tie(nullptr)->sync_with_stdio(false);solve();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/810693.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

『模拟赛』多校A层冲刺NOIP2024模拟赛04

『模拟赛记录』多校A层冲刺NOIP2024模拟赛04Rank 赤石场。A. 02表示法 签。 若干天前在洛谷随到过,不过当时只看了眼讨论区就走了www 还好本来不是很难。 发现大体上是一个拆分二的幂的问题,从大到小枚举 2 的幂,判断有没有这个幂只用比较大小关系,然后再对指数做一个同样的…

实现一个烟花效果

1. 首先创建一个烟花类,有烟花上升的效果,烟花爆炸的两种效果(爆炸型和球型)2. 创建线的属性方法,因为上升效果和爆炸效果都会用到3. 上升效果为了达到那种螺旋上升的效果可以通过sin函数实现一个点的偏移量4. 爆炸效果则是将随机生成多条半径不同的线5. 球形效果则是将规…

【Java】反射

Java中的反射机制 动态代理反射 允许对封装类的字段,方法和构造函数的信息进行编程访问 ==》 反射允许对成员变量,成员方法和构造方法的信息进行编程访问 基本操作:获取(获取class对象【字节码对象】) + 解剖 成员变量 Field —— 修饰符、名字、类型、赋值 构造方法 Cons…

DNShell

DNShell 一款基于DNS C2隧道的反弹shell工具。 支持 功能: 支持DNS-recordA-直连型 的C2隧道。 目标: Windows下基于Powershell的反弹。 Linux下基于ShellScript的反弹。 使用方法

【Redis】Redis学习笔记

概况 redis == remote Dictionary Server (远程字典服务) 基于内存的KV键值对内存数据库 作用:分布式缓存,与MySQL共同配合Redis -- 内存 MySQL -- 磁盘Redis -- NoSQL MySQL -- SQL内存存储 和 持久化(RDB+AOF)Redis支持一部将内存中的数据写入硬盘宕机 -- 可自行恢复高…

基于禁忌搜索算法的VRP问题求解matlab仿真,带GUI界面,可设置参数

1.程序功能描述基于禁忌搜索算法的VRP问题求解matlab仿真,带GUI界面,可设置参数。 2.测试软件版本以及运行结果展示MATLAB2022a版本运行 3.核心程序while COUNT<=Itertions ֲ L = zeros(Ant_Num,1); for i=1:Ant_Num Infor_Tabu_tmps = Infor_Tabu(i,:); R = Inf…

CMake 属性之全局属性

CMake 的全局属性是指在 CMake 配置过程中,对整个项目范围生效的设置。这些属性不同于目标 ( Target ) 属性或目录 ( Directory ) 属性,后者仅对特定的目标或目录生效。【写在前面】 CMake 的全局属性是指在 CMake 配置过程中,对整个项目范围生效的设置。 这些属性不同于目标…

自然人信息社工

人,是网络安全全流程中最大的弱点。针对人的攻击往往有出奇不意的效果。而想要利用人的弱点进行攻击,那么对目标的信息收集与了解就是非常重要的了。这篇文章记录了一些常用的用于对人进行身份信息收集的技术。这些技术常被用于溯源取证、社工攻击。 0x00 社工分析中的身份信…

Linux软中断ksoftirqd

前言 在上一篇 LINUX软中断-softirq的描述中,提到过ksoftirqd,这篇文章就介绍ksoftirqd ksoftirqd 是什么? ksoftirqd 是个内核线程,在创建的时候是绑定cpu的,每一个core对应生成一个ksoftirqd 线程 比如当前系统有4个core ~# ps aux | grep ksoftirqd root 3 0.0…

WPF Binding中的RelativeSource属性

一、简介 一个在Binding中比较重要的知识点——RelativeSource. 使用RelativeSource对象指向源对象。用这个可以在当前元素的基础上查找其他对象用于绑定到源对象。在实际使用Binding的过程中大部分时间Binding都放在了数据模板和控件模板中,(数据模板是控件模板用于定义控件…

信息学奥赛复赛复习15-CSP-J2022-01乘方-数据类型、类型转换、数据类型溢出、指数、模拟指数运算

PDF文档公众号回复关键字:202410091 P8813 [CSP-J 2022] 乘方 [题目描述] 小文同学刚刚接触了信息学竞赛,有一天她遇到了这样一个题:给定正整数 a 和 b,求 a^b 的值是多少。 a^b 即 b 个 a 相乘的值,例如 2^3 即为 3 个 2 相乘,结果为 222=8 “简单!”小文心想,同时很快…

Postman 教程:新手必备的操作指南

API 已经成为连接不同系统和服务的重要桥梁,无论你是前端开发者、后端工程师还是测试人员,掌握 API 的开发和测试技能都是非常重要的。Postman 是一个广受欢迎的 API 开发工具,它不仅能够帮助你轻松发送 HTTP 请求,还提供了强大的测试、调试和协作功能。本系列教程旨在帮助…