首页 > 其他分享 >2024牛客多校第七场

2024牛客多校第七场

时间:2024-08-08 22:19:06浏览次数:18  
标签:ch int sum 第七场 2024 牛客 哈希 getchar lld

K

贪心地先凑出前后端后,中间的部分是本质不同的子序列个数

然后枚举可以重叠的部分,如果可以重叠肯定是回文后缀

有不少细节,比如空串,重叠部分要求后面的能取到

#include<cstdio>
#include<iostream>
#define int long long 
#define ULL unsigned long long
using namespace std;
const int P=1e9+7;
const int N=1e6+505;
const int K=97;
int n,m,res;
int dp[N],last[N];
ULL pre[N],suf[N],pow[N];
string s,t; 
int check(int x){
    return pre[x]==suf[x];
}
signed main(){
    cin >> n >> m;
    cin >> s >> t;
    s=' '+s+' ';
    t=' '+t+' ';
    int l=1,r=n;
    pow[0]=1;
    for (int i=1;i<=m;i++)
        pow[i]=pow[i-1]*K;
    for (int i=m;i>=1;i--){
        pre[i]=pre[i+1]*K+(t[i]-'a');
        suf[i]=suf[i+1]+pow[m-i]*(t[i]-'a');
    }
        
    for (int i=1;i<=m;i++){
        while(l<=n&&s[l]!=t[i]) l++;
        //if (l>n) break;
        l++;        
    }
    for (int i=1;i<=m;i++){
        if (l<=r+1) res+=check(i);
        while(r>0&&s[r]!=t[i]) r--;
        //if (r<=0) break;
        r--;
    }
    if (l<=r){
        dp[l-1]=1;
        for (int i=l;i<=r;i++){
            if (last[s[i]]) dp[i]=(dp[i-1]*2-dp[last[s[i]]-1]+P)%P;
                else dp[i]=dp[i-1]*2%P;
            last[s[i]]=i;        
        }

        res=(res+dp[r])%P;    
    }
    if (r==l-1) res=(res+1)%P;
    cout << res << endl;
    return 0;
}

 

J

考虑极限的情况,最极限就是两端能否扫到

没想到极限的话就可能要算不等式

#include<bits/stdc++.h>
using namespace std;

inline int read()
{
    int x=0;bool f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())f^=(ch=='-');
    for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<1)+(x<<3)+(ch^48);
    return f?x:-x;
}
void Kafka()
{
    int l=read(),x=read(),y=read();
    if(1LL*x*x+1LL*y*y<=1LL*l*l) printf("Yes\n0\n");
    else if(1LL*(l-x)*(l-x)+1LL*y*y<=1LL*l*l) printf("Yes\n%d\n",l);
    else puts("No");    
}
signed main()
{
    for(int T=read();T--;) Kafka();
    return 0;
}

 

I

首先可以二分枚举,初始机器n越多,最后能造成的伤害越多

肯定是先造新的机器,直到不能再造,然后全都拿去打击怪物

造新的机器这个问题就转化成:

给定n,每次用m个换新的k个,最后能换出多少个。

可以写出递推式子f(n)=f(n-m+k)+m,可以把-m+k写成-c

等价为f(n)=f(n-c)+m=f(n-2c)+2m=...

但是不能直接把n减到小于c,因为要满足先够-m然后再+k,这里就特判一下

#include<bits/stdc++.h>
using namespace std;

inline int read()
{
    int x=0;bool f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())f^=(ch=='-');
    for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<1)+(x<<3)+(ch^48);
    return f?x:-x;
}
#define int long long
int m,k,h;
int check(int n,int h){
    if(n<m){
        if(n<h) return 0;
        else return 1;
    }
    int c=m-k;
    int sum=((n-m)/c+1)*m;
    sum+=(n-m)%c+k;
    if(sum>=h) return 1;
    else return 0;
}
void solve(){
    cin>>m>>k>>h;
    if(h==0) {
        cout<<0<<"\n";
        return;
    }
    if(k==m){
        if(m-1>=h) {
            cout<<h<<"\n";
        }
        else cout<<m<<"\n";
    }
    else {
        int l=0,r=h,ans=-1;
        while(l<=r){
            int mid=(l+r)>>1;
            if(check(mid,h)){
                ans=mid;
                r=mid-1;
            }
            else l=mid+1;
        }
        cout<<ans<<"\n";
    }
}
signed main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t;cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

 

 

D

队友用一种神奇的哈希过了

把所有数出现的次数哈希

原本哈希字符串是abcdeaa,给它哈希成一个值

同理用cnt[x]表示x出现的次数,cnt[1]cnt[2]cnt[3]..cnt[n],给它哈希成一个值

则在i这个位置时,能匹配得上的一定是之前位置哈希值也一样的数

但是有一个问题!!

能匹配得上的位置也可能是k的倍数,所以再用一个双指针维护一下

#include<bits/stdc++.h>
#define int long long
using namespace std;
const __int128 P=1000000000000000003;
const int N=2e5+505;
inline int read()
{
    int x=0;bool f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())f^=(ch=='-');
    for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<1)+(x<<3)+(ch^48);
    return f?x:-x;
}
int n,k,m;
int a[N],h[N],dp[N];
__int128 hs[N];
map<int,int> f,g;
struct lst{
    vector<int> c,d;
    int n,t,i=1;
    int sum=0;
    void init(int _n,int _t){
        n=_n;
        t=_t;
        c.resize(n+5);
        d.resize(n+5);
    }
    void next(){
        int p=a[i];
        c[p]++;
        d[p]++;
        if (t==-1) g[sum]+=t;
        sum=(sum+hs[p])%P;
        //printf("p=%lld\n",p);
        if (d[p]==k){
            d[p]=0;
            sum=(sum-hs[p]*k%P+P)%P;
        }
        if (t==1) g[sum]+=t;
        i++;
    }
};
void test(){
    for (int i=0;i<=n;i++)
        printf("a[%lld]=%lld\n",i,a[i]);
    for (int i=1;i<=n;i++)
        cout << (long long)hs[i] << endl;
}
void test_map(){
    for (auto i=g.begin();i!=g.end();i++){
        printf("%lld %lld\n",i->first,i->second);
    }
}
void work(){
    n=read(); k=read();
    for (int i=1;i<=n;i++)
        a[i]=read();
    f.clear(); g.clear(); 
    
    for (int i=1;i<=n;i++)
        f[a[i]]=0;
    m=0;
    for (auto i=f.begin();i!=f.end();i++)
        i->second=++m;
    
    for (int i=1;i<=n;i++)
        a[i]=f[a[i]];
    lst p,q;
    p.init(n,1);
    q.init(n,-1);
    int res=0;
    //test();
    g[0]=1;
    for (int i=1;i<=n;i++){
        int pos=a[i];
        p.next();
        while(p.c[pos]-q.c[pos]>k){
            q.next();
            //printf("%lld %lld q.i=%lld\n",p.c[pos],q.c[pos],q.i);
        }
        
        res+=g[p.sum]-1;
        //printf("add %lld:%lld %lld\n",i,g[p.sum]-1,p.sum);
        //test_map();
        //printf("p.i=%lld q.i=%lld\n",p.i,q.i);
    }
    
    
    cout << res << endl;
}
signed main()
{
    hs[0]=0;
    hs[1]=1;
    for (int i=2;i<N;i++){
        hs[i]=hs[i-1]*N%P;
    }
    int T;
    T=read();
    while(T--) work();
    return 0;
}

 

标签:ch,int,sum,第七场,2024,牛客,哈希,getchar,lld
From: https://www.cnblogs.com/liyishui2003/p/18349845

相关文章

  • 2024牛客多校第八场
    E观察到s(m)<=108,所以r是可以枚举的但是枚举完后再开根号,时间复杂度为O(T*r*sqrt(n))≈O(100*100*1e6)赛时还想了一种自认为更优的做法。考虑枚举i,枚举完i就能得到r,判断是否满足条件(当然,就像分解质因数那样,n/i也要判断)然后直接这么写会出点小问题,比如11=10*1+1,i=1时11%1=0在......
  • win7一键修复所有dll缺失详细方法,7个dll修复方法深度解析(2024)
    dll文件是一种包含函数和其他关键信息的文件,供Windows应用程序使用。虽然大多数普通用户对.dll文件的具体工作原理并不熟悉,但这些文件对于系统应用来说是至关重要的。通常情况下,人们在遇到因DLL文件缺失或损坏而导致的错误时,才会接触到它们。对于非专业用户来说,理解这些错......
  • 牛客多校 A 题题解
    牛客多校8-AHaitangandGameGivenaset\(\textstyleS\),dXqwqandHaitangtaketurnsperformingthefollowingoperations,withdXqwqgoingfirst:Findapair\(\textstyle(x,y)\)suchthat\(\textstylex,y\inS\)and\(\textstyle\gcd(x,y......
  • 2024年最新免费AI大模型API汇总及国内大模型使用教程(附代码)
    免费大模型API一览大模型免费版本免费限制控制台(api_key等)API文档讯飞星火大模型spark-litetokens:总量无限;QPS:2;(每秒发送的请求数)有效期:不限访问链接访问链接百度千帆大模型平台ERNIE-Speed-8KRPM=300,TPM=300000(RPM是每分钟请求数(RequestsPerMinute),TPM是指每分......
  • 第二十天的学习(2024.8.8)Vue拓展
    昨天的笔记中,我们进行的项目已经可以在网页上显示查询到数据库中的数据,今天的笔记中将会完成在网页上进行增删改查的操作 1.删除表中数据现在网页上只能呈现出数据库中的数据,我们首先添加一个删除按钮,使其可以对数据库数据进行删除操作<template#default="scope"><e......
  • GMOJ 8101. 【2024年SD省队集训Day8】 正交向量
    效率时间复杂度:\(O(Tn\times3^9\times9)\)。没有任何卡常,能在\(1.08\)s内过hack.txt,而CHJ的代码在同样情况下跑了\(39\)s,LZY要用\(34\)s,PWX要用\(75\)s。但是在GMOJ上要用\(770\)ms,是目前比较劣的解。思路以下关于数字的第几位都是从\(0\)开始,从最低位到最......
  • 2024北京集训trick合集
    atcoderARC092F给定一张\(n\)个点\(m\)条边的有向图,判断每一条边反向后是否改变图中强连通分量的数量。数据范围:\(n\le1000\\\\m\le200000\)先跑一遍tarjan,然后问题转化为判断每个直接相连的两点在不经过其连边的情况下是否互通。对每个点dfs维护前缀和后缀能否回......
  • 2024睿抗机器人开发者大赛(RAICOM) CAIP编程技能赛 国一
    最后91分,国一。前几题都AK了,最后一题先是输出0,得了个1分。花了一个小时都没解决这题,难受ing,其实到最后差不多要改对了(降落那一部分没时间改),但是没时间了,hhhh。拿到国一,简直圆梦啦!!!本科拿的国三,差0.02秒就是国二,从此内心蒙上阴影。哭死ing研一终于拿了个编程比赛的国一,也算......
  • 2024年深圳市工业设计发展扶持计划申报时间
    为了进一步提升深圳市工业设计水平,加快工业设计与制造业的深度融合,2024年深圳市工业设计发展扶持计划现已全面启动。该计划旨在通过资金支持、政策优惠等多种方式,鼓励和支持工业设计企业及个人进行技术创新和产品开发,以增强深圳工业设计在全球市场的竞争力。对于符合条件的企业......
  • 2024年苏州市跨国公司地区总部和功能性机构申报临近截止时间
    苏州市跨国公司地区总部和功能性机构申报的截止时间已经迫在眉睫——8月12日。对于尚未提交申报材料的企业,现在是时候加快步伐,把握这最后的申报机会了。项目介绍苏州市一直致力于吸引和培育跨国公司地区总部及功能性机构,以推动外资总部经济的发展。截至目前,苏州已成功吸引了......