多校A层冲刺NOIP2024模拟赛04
T1、02表示法
竟然有出题人敢出高精度(其实只是一个把string转成01串),开场看出记搜后十分犹豫到底要不要写高精,徘徊很久还是写了个小高精。
码(
/*
GGrun
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define mk make_pair
#define ps push_back
#define fi first
#define se second
const int N=2e6+10,inf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f,mod=1e9+7;
inline ll read(){
char c=getchar();ll x=0,f=1;
while(!isdigit(c))f=c=='-'?-1:1,c=getchar();
while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
string f[1010];
bool vis[1010];
inline string sol(int man){
if(vis[man])return f[man];
vis[man]=1;
for(int i=20;i>=0;--i){
if((man>>i)&1){
if(i==0)f[man]+="2(0)+";
else if(i==1)f[man]+="2+";
else f[man]=f[man]+"2("+sol(i)+")+";
}
}
f[man].pop_back();
return f[man];
}
string ans,s;
inline void chu(string &s){
int len=s.size();
for(int i=0;i<len;++i){
if((s[i]-'0')&1)s[i+1]+=10,s[i]--;
s[i]=((s[i]-'0')>>1)+'0';
}
if(s[0]=='0')s.erase(s.begin());
}
bool dan[N];
signed main(){
// #ifndef ONLINE_JUDGE
freopen("pow.in","r",stdin);
freopen("pow.out","w",stdout);
// #endif
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
vis[1]=vis[2]=1;f[1]="2(0)",f[2]="2";
cin>>s;
int len=0;
while(s.size()){
if((s[s.size()-1]-'0')&1)dan[len]=1,--s[s.size()-1];
chu(s);
++len;
// cout<<s<<endl;
}
for(int i=len-1;i>=0;--i){
if(dan[i]){
if(i==0)ans+="2(0)+";
else if(i==1)ans+="2+";
else ans=ans+"2("+sol(i)+")+";
}
}
ans.pop_back();
cout<<ans;
}
T2、子串的子串
典型的扫描线,套路转化成pre,直接哈希用unordered_map记一下就行。
然后发现其实不行!!!!!!!!!
卡了半天,没想到怎么处理哈希冲突,后来T3给了点启发(只不过启发的不是正解),想到枚举的字符串每次只差一个字符,于是就可以用trie树去记他们的pre。
然后就炸空间了!
后来硬生生卡到了90分,空间还是开不下。
好吧,说说正解,其实注意到大部分字符串的长度不一样,长度也是他们本身的key值,可以用来减少哈希冲突,所以还是用unordered_map,每次枚举长度相同的字符串,然后就可以了。
码(
/*
GGrun
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define mk make_pair
#define ps push_back
#define fi first
#define se second
const int N=2e6+10,inf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f,B=123;
inline ll read(){
char c=getchar();ll x=0,f=1;
while(!isdigit(c))f=c=='-'?-1:1,c=getchar();
while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,q;
char s[5000];
ull hs[5000],ci[5000];
unordered_map<ull,int > pre;
inline ull hx(int l,int r){
return (hs[r]-hs[l-1]*ci[r-l+1]);
}
int c[3005];
inline void add(int x,int y){while(x<=n)c[x]+=y,x+=x&-x;}
inline int ask(int x){int ans=0;while(x)ans+=c[x],x^=x&-x;return ans;}
struct jj{
int l,r,id;
inline bool operator <(const jj&x)const{return l<x.l;}
}Q[N];
struct xian{
int l,v;
};
vector<xian> sao[3005];
int ans[N];
signed main(){
// #ifndef ONLINE_JUDGE
freopen("substring.in","r",stdin);
freopen("substring.out","w",stdout);
// #endif
// double ti=clock();
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
n=read(),q=read();
scanf("%s",s);
ci[0]=1;
for(int i=0;i<n;++i){
hs[i+1]=(hs[i]*B+s[i]);
ci[i+1]=ci[i]*B;
}
for(int i=1;i<=q;++i){
Q[i].l=read(),Q[i].r=read(),Q[i].id=i;
}
sort(Q+1,Q+1+q);
for(int len=1;len<=n;++len){
pre.clear();
for(int i=1,j=i+len-1;j<=n;++j,++i){
ull man=hx(i,j);
sao[i+1].ps({j,-1});sao[pre[man]+1].ps({j,1}),pre[man]=i;
}
}
for(int i=0,j=1;i<=n;++i){
for(auto k:sao[i]){
add(k.l,k.v);
}
while(j<=q&&Q[j].l==i)
ans[Q[j].id]=ask(Q[j].r),++j;
}
for(int i=1;i<=q;++i)
cout<<ans[i]<<'\n';
}
听说还可以用SAM做,不会,run了。
T3、魔法咒语
肯定得用trie树,先正着插一遍,能却确定不同的前缀有多少个,倒着插一遍能确定不同的后缀有多少个。把他们乘起来,再加上长度唯一的字符串(不重)的个数就是可能的方案数。
但是还要去重,怎么去呢,一个字符串会被不同前后缀组成多次,说明中间有一些字符即可以从前缀的来,也可以从后缀得来。所以对于一个字符,如果他既在前缀trie树中出现过,又在后缀trie树中出现过,那么这个字符便有了到底应该在前面出现还是应该在后面出现的选择,去重便要减一。
但是还有规定,前后两个字符串不能为空,那么对于两颗trie树来说,在第一层(根的儿子们)是必选的,他们不能计数。除去这些点后,每种小写字母在两棵树中的出现次数分别是 $ cnt1_i , cnt2_i $
那么最后答案再减去 $ \sum_{i ∈ 小写字母 }{cnt1_i * cnt2_i} $ 即可。
码(
/*
GGrun
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define mk make_pair
#define ps push_back
#define fi first
#define se second
const int N=2e6+10,inf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f,mod=1e9+7;
inline ll read(){
char c=getchar();ll x=0,f=1;
while(!isdigit(c))f=c=='-'?-1:1,c=getchar();
while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,cnt,son[10001*40][26],num1[26],num2[26];
string s[10001];
bool f[10001*40],dan[26];
inline void ins(string &s){
int now=0,len=s.size();
for(int i=0;i<len;++i){
if(!son[now][s[i]-'a'])son[now][s[i]-'a']=++cnt;
f[now]=1;
now=son[now][s[i]-'a'];
}
}
inline void sol(int num[],int now){
for(int i=0;i<26;++i)
if(son[now][i])num[i]+=now!=0,sol(num,son[now][i]);
}
signed main(){
// #ifndef ONLINE_JUDGE
freopen("magic.in","r",stdin);
freopen("magic.out","w",stdout);
// #endif
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;++i)
cin>>s[i],ins(s[i]);
ll ans=0,cnt1=cnt;
sol(num1,0);
for(int i=0;i<=cnt;++i){
for(int j=0;j<26;++j)
son[i][j]=0;
}
cnt=0;
for(int i=1;i<=n;++i){
// cout<<s[i].size()<<endl;
if(s[i].size()==1&&!dan[s[i][0]-'a'])++ans,dan[s[i][0]-'a']=1;
reverse(s[i].begin(), s[i].end()),ins(s[i]);
}
sol(num2,0);
ans+=cnt1*cnt;
for(int i=0;i<26;++i)
ans-=(ll)num1[i]*num2[i];
cout<<ans;
}
T4、表达式
用线段树维护函数答案。
但是还得用CRT,好吧其实数论那块我根本没学明白。场上骗了30分,写的分块,忘了写线段树更优了,痛失10分。
简单复习(贺)了一下
码(
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define mk make_pair
#define ps push_back
#define fi first
#define se second
const int N=1e6+10,inf=0x3f3f3f3f,B=sqrt(1e9);
const ll linf=0x3f3f3f3f3f3f3f3f;
inline ll read(){
char c=getchar_unlocked();ll x=0,f=1;
while(!isdigit(c))f=c=='-'?-1:1,c=getchar_unlocked();
while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar_unlocked();
return x*f;
}
int n,m,p,X[N],mod,t;
char op[N];
int ans[800005][8][30],ny[8],cntmod,mo[30];
inline ll qpow(ll x,ll y,ll mod){
ll ans=1;
while(y){
if(y&1)ans=ans*x%mod;
x=x*x%mod;y>>=1;
}
return ans;
}
inline void ad(int k,int pos){
if(op[pos]=='+'){
for(int i=1;i<=cntmod;++i){
ll mod=mo[i];
for(int j=0;j<mod;++j)
ans[k][i][j]=(j+X[pos])%mod;
}
}
else if(op[pos]=='*'){
for(int i=1;i<=cntmod;++i){
ll mod=mo[i];
for(int j=0;j<mod;++j)
ans[k][i][j]=((ll)j*X[pos])%mod;
}
}
else{
for(int i=1;i<=cntmod;++i){
ll mod=mo[i];
for(int j=0;j<mod;++j)
ans[k][i][j]=qpow(j,X[pos],mod);
}
}
}
inline void jian(int k,int l,int r){
if(l==r){
ad(k,l);
return;
}
int mid=l+r>>1;
jian(k<<1,l,mid),jian(k<<1|1,mid+1,r);
for(int i=1;i<=cntmod;++i){
ll mod=mo[i];
for(int j=0;j<mod;++j)
ans[k][i][j]=ans[k<<1|1][i][ans[k<<1][i][j]];
}
}
inline void add(int k,int l,int r,int pos){
if(l==r){
ad(k,l);
return;
}
int mid=l+r>>1;
pos<=mid?add(k<<1,l,mid,pos):add(k<<1|1,mid+1,r,pos);
for(int i=1;i<=cntmod;++i){
ll mod=mo[i];
for(int j=0;j<mod;++j)
ans[k][i][j]=ans[k<<1|1][i][ans[k<<1][i][j]];
}
}
signed main(){
freopen("expr.in","r",stdin);
freopen("expr.out","w",stdout);
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
t=read();
n=read(),m=read(),mod=read();
for(int i=1;i<=n;++i){
scanf(" %c",&op[i]);X[i]=read();
}
if(t<=3){
for(int i=1,opp,pos,x;i<=m;++i){
opp=read();
if(opp==1){
x=read()%mod;
for(int j=1;j<=n;++j){
if(op[j]=='+')x=(x+X[j])%mod;
else if(op[j]=='*')x=(ll)x*X[j]%mod;
else x=qpow(x,X[j],mod);
}
cout<<x<<'\n';
}
else pos=read(),op[pos]=getchar_unlocked(),X[pos]=read();
}
}
else{
ll p=mod;
for(int i=2;i*i<=mod;++i){
if(p%i==0){
ll op=1;
while(p%i==0)op=op*i,p/=i;
mo[++cntmod]=op;
for(int j=1,man=mod/op;j<op;++j)
if((ll)man*j%op==1){ny[cntmod]=j;break;}
}
}
if(p>1){
mo[++cntmod]=p;
for(int j=1,man=mod/p;j<p;++j)
if((ll)man*j%p==1){ny[cntmod]=j;break;}
}
jian(1,1,n);
for(int i=1,opp,pos,x;i<=m;++i){
opp=read();
if(opp==1){
x=read();
ll op=0;
for(int j=1;j<=cntmod;++j){
op=(op+(ll)mod/mo[j]*ny[j]%mod*ans[1][j][x%mo[j]]%mod)%mod;
}
cout<<op<<'\n';
}
else{
pos=read();op[pos]=getchar_unlocked();X[pos]=read();
add(1,1,n,pos);
}
}
}
}
总结
这场题主要是T2学了个unordered_map如何更优秀的避免哈希冲突,那就是多运用它们本身自带的key值。
T4其实感觉线段树部分会了,但不知道下次还会不会用CRT了。
P
其实我没有图片(
多校A层冲刺NOIP2024模拟赛04的更多相关文章
- 多校B层冲刺NOIP20211111模拟12
题面:PDFhttp://xn--gwt928b.accoders.com/pdf/10248/10248.pdfhttp://xn--gwt928b.accoders.com/pdf/10248/1 ...
- 【CJOJ P1957】【NOIP2010冲刺十模拟赛】数字积木
[NOIP2010冲刺十模拟赛]数字积木 Description 小明有一款新式积木,每个积木上都有一个数,一天小明突发奇想,要是把所有的积木排成一排,所形成的数目最大是多少呢? 你的任务就是读入n个 ...
- 冲刺Noip2017模拟赛7 解题报告——五十岚芒果酱
1.二叉树(binary) .二叉树 (binary.cpp/c/pas) [问题描述] 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: ()若左子树不空,则左子树上所有结点的值均小于它的根结 ...
- 冲刺Noip2017模拟赛8 解题报告——五十岚芒果酱
1.鼎纹 [问题描述] 据说鼎纹的 种制造 式是 铜模印出来的,这是我国古代劳动 智慧 的结晶.铜模印过的地 ,会留下深深的印记,经过时间的炼化,洗 练成历史的遗存. 聪明的古代劳动人民拥有一个 a ...
- 冲刺Noip2017模拟赛4 解题报告——五十岚芒果酱
题1 韬韬抢苹果(apple) [问题描述] 又到了收获的季节,树上结了许多韬韬,错了,是许多苹果,有很多个小韬韬都来摘苹 果.每个韬韬都想要最大的苹果,所以发生了争执,为了解决他们的矛盾,出题人定了 ...
- 冲刺Noip2017模拟赛2 解题报告——五十岚芒果酱
题1 牛跑步(running) [题目描述] 新牛到部队,CG 要求它们每天早上搞晨跑,从 A 农场跑到 B 农场.从 A 农场到 B 农场中有 n- 个路口,分别标上号,A 农场为 号,B 农场为 ...
- 冲刺Noip2017模拟赛1 解题报告——五十岚芒果酱
题1 国际象棋(chess) [问题描述] 有N个人要参加国际象棋比赛,该比赛要进行K场对弈.每个人最多参加2场对弈,最少参加0场对弈.每个人都有一个与其他人都不相同的等级(用一个正整数来表示).在对 ...
- 冲刺Noip2017模拟赛6 解题报告——五十岚芒果酱
1.ksum(ksum) [问题描述] Peter喜欢玩数组.NOIP这天,他从Jason手里得到了大小为n的一个正整数 数组. Peter求出了这个数组的所有子段和,并将这n(n+)/2个数降序排序 ...
- 冲刺Noip2017模拟赛5 解题报告——五十岚芒果酱
1. 公约数(gcd) [问题描述] 给定一个正整数,在[,n]的范围内,求出有多少个无序数对(a,b)满足 gcd(a,b)=a xor b. [输入格式] 输入共一行,一个正整数n. [输出格式] ...
- 冲刺Noip2017模拟赛3 解题报告——五十岚芒果酱
题1 素数 [问题描述] 给定一个正整数N,询问1到N中有多少个素数. [输入格式]primenum.in 一个正整数N. [输出格式]primenum.out 一个数Ans,表示1到N中有多少个素 ...
随机推荐
- 阿里2021年春季实习笔试题(最后一道大题)(2020 China Collegiate Programming Contest, Weihai Site) (C. Rencontre codeforces.com/gym/102798)
实验室的慕师弟phd马上要毕业了,正准备先找个实习,投了阿里2021年春季实习的招聘,遇到最后一道编程大题没有思路事后找到了该题的最原始出处,即 2020 China Collegiate Progr ...
- 安装windows11的注意事项
进入到安装界面后,在选择时间和货币格式的时候选择:英语(世界),据说这样可以避免第三方软件的安装. KMS命令: slmgr /ipk W269N-WFGWX-YVC9B-4J6C9-T83GX sl ...
- 高校校园网下电脑IP是不是公网IP
突然想到一个问题,那就是高校校园网中的IP地址是不是公网IP,如果不是公网IP那么就是使用net后的共享IP,还或者是部分人用公网IP然后另一部分人使用net后的共享IP??? =========== ...
- 为python安装扩展模块时报错——error: invalid command 'bdist_wheel'
具体过程: devil@hp:~/lab$ ./bazel-bin/python/pip_package/build_pip_package /tmp/dmlab_pkg2022年 10月 03日 星 ...
- stm32g070 usart 中断问题: 开启接收中断 RXNEIE 需要注意ISR的错误类型,否则会进入中断。
usart 中断问题: 开启接收中断 RXNEIE 需要注意ISR的错误类型,否则会进入中断. 调试时发现,如果ISR的ORE和FE置位,而此时要是使能RX中断(RXNEIE置位)就会进入中断复位程序 ...
- uni-app和vue及微信小程序的异同
uni-app和vue的区别1.目录不同 uni-app目录依赖原生小程序风格,比如分包的概念 vue中对不同的页面只需要在views文件夹中定义不同组件,然后配置路由跳转就行了,所有页面都是这样, ...
- spring boot 若依系统整合Ueditor,部署时候上传图片错误解决
spring boot 若依系统整合Ueditor,部署时候上传图片错误解决 前言:国庆假期找了个ruoyi版本的cms玩玩,从git上看,介绍如下图: 后台部分截图: 编辑 编辑 编辑 ...
- 呵,老板不过如此,SQL还是得看我
2018年7月,大三暑假进行时,时间过得飞快,我到这边实习都已经一个月了. 我在没工作之前,我老是觉得生产项目的代码跟我平时自学练的会有很大的区别. 以为生产项目代码啥的都会规范很多,比如在接口上会做 ...
- 《Effective TypeScript》条款21 - 类型扩展
本文主要通过一些实际的代码示例,来帮助大家理解什么是类型扩展,本文主要内容如下: 什么是类型扩展 代码示例 总结 什么是类型扩展? TypeScript 需要从你指定的单一值中决定一组可能的值,这个过 ...
- Coze插件发布!PDF转Markdown功能便捷集成,打造你的专属智能体
近日,TextIn开发的PDF转Markdown插件正式上架Coze平台. 在扣子搜索"pdf转markdown",或在Coze平台搜索"pdf2markdown&quo ...