首页 > 其他分享 >2022 CCPC湖北省赛

2022 CCPC湖北省赛

时间:2024-02-20 16:24:05浏览次数:45  
标签:cnt idx int void CCPC cin seg 2022 湖北省

2022 CCPC湖北省赛

​ 这场打的怎么说,很难受。过年来与几个亲戚家的孩子见了面,被灌了不少白酒,没感觉什么酱香有啥好喝的,脑子倒是快成浆糊了。怒了,加训。题解里签到题的做法会写的简单点,这个[每日一棵splay](2022 Hubei Provincial Collegiate Programming Contest 题解 A B F J K L - 知乎 (zhihu.com))写得好。

签到

K. PTT

​ 牛魔的签到题弄一堆洋文,看不懂一点。平常帮我读题那个队友还去了namomo camp,这题读得很痛苦

void solve(){
    ll n;double c;cin>>n>>c;
    double ans=0;
    if(n>=10000000)ans=2.0;
    else if(n>9800000)ans=1.0+1.0*(n-9800000)/200000;
    else ans=1.0*(n-9500000)/300000;
    cout<<max(ans+c,0.0)<<endl;
}
signed main(){
    std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
    srand((unsigned)time(NULL));
    cout << fixed << setprecision(10);
    int t;std::cin>>t;while(t--)
    solve();
}

B. Potion(easy version)

​ 假设当前的浓度为 :\(x:y\) ,那么我们发现上一次的浓度比会是:\((ax-by):(a+b)*y\),(或者\(x\)与\(y\)互换位置)。这个结果是通过先得出下一次的浓度比为:\((ax+bx+by):ay\),(或者x和y互换位置)。然后再反推得到的。当 \(a=b\) 的时候,显然\(x\)与\(y\)在每一次结果中不会交换位置,即大的那个当\(x\),然后我们带入式子,即可。复杂度为\(O(logn)\)

void solve(){
    ll a,b,x,y;cin>>a>>b>>x>>y;
    ll ans=1;
    while(1){
        if(a<b)swap(a,b);
        if(a%2!=b%2){
            cout<<-1<<"\n";
            return ;
        }
        ans++;
        a-=b;a/=2ll;
        if(a==0){
            cout<<ans<<"\n";return ;
        }
    }
}

L.Chtholly and the Broken Chronograph

​ 线段树模板。创建一个cnt来维护即可。

#include<bits/stdc++.h>
#define fi first
#define se second
#define ll long long
#define lowbit(x) (x&(-x))
#define lson l,mid,k<<1
#define rson mid+1,r,k<<1|1
#define lt k<<1
#define rt k<<1|1
using namespace std;
typedef pair<int,int> pii;
const int N=1e5+10;
typedef pair<int,int> pii;
struct segg{
    ll s,lazy;
    int cnt=0;
}seg[N<<2];
void build1(int l,int r,int k){
    if(l==r){cin>>seg[k].s;return ;}
    int mid=l+r>>1;
    build1(lson),build1(rson);
    seg[k].s=seg[lt].s+seg[rt].s;
}
void build2(int l,int r,int k){
    if(l==r){cin>>seg[k].cnt;seg[k].cnt^=1;return ;}
    int mid=l+r>>1;
    build2(lson),build2(rson);
    seg[k].cnt=seg[lt].cnt+seg[rt].cnt;
}
void pushdown(int l,int r,int k){
    if(l==r)return ;
    seg[lt].lazy+=seg[k].lazy;
    seg[rt].lazy+=seg[k].lazy;
    int mid=l+r>>1;
    seg[lt].s+=seg[k].lazy*(mid-l+1-seg[lt].cnt);
    seg[rt].s+=seg[k].lazy*(r-mid-seg[rt].cnt);
    seg[k].lazy=0;
}
void update(int l,int r,int k,int x,int y,ll z){
    pushdown(l,r,k);
    if(x<=l&&r<=y){
        seg[k].s+=(ll)(r-l+1ll-seg[k].cnt)*z;
        seg[k].lazy+=z;
        return ;
    }
    int mid=l+r>>1;
    if(x<=mid)update(lson,x,y,z);
    if(y>mid)update(rson,x,y,z);
    seg[k].s=seg[lt].s+seg[rt].s;
}
void update1(int l,int r,int k,int idx){
    pushdown(l,r,k);
    seg[k].cnt++;
    if(l==r)return ;
    int mid=l+r>>1;
    if(idx<=mid)update1(lson,idx);
    if(idx>mid)update1(rson,idx);
}
void update2(int l,int r,int k,int idx){
    pushdown(l,r,k);
    seg[k].cnt--;
    if(l==r)return ;
    int mid=l+r>>1;
    if(idx<=mid)update2(lson,idx);
    if(idx>mid)update2(rson,idx);
}
ll query(int l,int r,int k,int x,int y){
    pushdown(l,r,k);
    if(x<=l&&r<=y)return seg[k].s;
    ll res=0;
    int mid=l+r>>1;
    if(x<=mid)res+=query(lson,x,y);
    if(y>mid)res+=query(rson,x,y);
    return res;
}
void solve(){
    int n,m;cin>>n>>m;
    build1(1,n,1);
    build2(1,n,1);
    while(m--){
        int op;cin>>op;
        if(op==1){
            int idx;cin>>idx;
            update1(1,n,1,idx);
        }
        else if(op==2){
            int idx;cin>>idx;
            update2(1,n,1,idx);
        }
        else if(op==3){
            int x,y,z;cin>>x>>y>>z;
            update(1,n,1,x,y,z);
        }
        else{
            int x,y;cin>>x>>y;
            cout<<query(1,n,1,x,y)<<"\n";
        }
    }
}
signed main(){
    std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
    srand((unsigned)time(NULL));
    //int t;std::cin>>t;while(t--)
    solve();
}

J. Palindrome Reversion

​ 猜了个结论,和队友聊了会也没证明出来。具体是先两边往中间枚举,第一个不一样的坐标作为reverse子区间的一个端点,然后枚举另一个端点,哈希判断reverse后整体是否为回文。后来看了大佬[每日一棵splay](2022 Hubei Provincial Collegiate Programming Contest 题解 A B F J K L - 知乎 (zhihu.com))的博客,想到其实这一步就是把那些已经是回文的字符删去了。这么说看起来很弱智,但是我认为还是能从中汲取到一些养分的。另外上面提到的这位大佬最近好像退役了,正在考研,那我在这里也祝他能考上。

​ 赛后写这题的时候n和m写反了,以为是哈希写错了,de了好久。

typedef unsigned long long ull;
typedef pair<ull,ull> puu;
const ull mod1=19260817;
const ull mod2=19660813;
const ull base=233;

const int N=1e6+10;
typedef pair<int,int> pii;

ull pw1[N],pw2[N];
void initpw(){
    pw1[0]=pw2[0]=1;
    for(int i=1;i<=1e6;i++){
        pw1[i]=pw1[i-1]*base%mod1;
        pw2[i]=pw2[i-1]*base%mod2;
    }
}
puu gethash(char c){
    return {c*base%mod1,c*base%mod2};
}
void solve(){
    string ss;cin>>ss;
    int n=ss.size();
    string s="~";s+=ss;
    int flag=-1;
    for(int i=1;i<=n;i++){
        if(s[i]!=s[n-i+1]){flag=i;break;}
    }
    if(flag==-1){
        cout<<1<<" "<<1<<"\n";return ;
    }
    int m=n;
    string a="~";
    for(int i=flag;i<=n-flag+1;i++)a+=s[i];
    n=a.size()-1;
    puu hash1={0,0},hash2={0,0};
    for(int i=1;i<=n;i++){
        puu temp=gethash(a[i]);
        hash1.fi=(hash1.fi+temp.fi*pw1[i-1]%mod1)%mod1;
        hash1.se=(hash1.se+temp.se*pw2[i-1]%mod2)%mod2;
        hash2.fi=(hash2.fi+temp.fi*pw1[n-i]%mod1)%mod1;
        hash2.se=(hash2.se+temp.se*pw2[n-i]%mod2)%mod2;
    }
    puu hash3={0,0},hash4={0,0};
    for(int i=1;i<n;i++){
        puu temp=gethash(a[i]);
        hash3.fi=(hash3.fi+temp.fi*pw1[i-1]%mod1)%mod1;
        hash3.se=(hash3.se+temp.se*pw2[i-1]%mod2)%mod2;
        hash4.fi=(hash4.fi*base%mod1+temp.fi)%mod1;
        hash4.se=(hash4.se*base%mod2+temp.se)%mod2;
        puu k1={(hash1.fi+hash4.fi+mod1-hash3.fi)%mod1,(hash1.se+hash4.se+mod2-hash3.se)%mod2};
        puu k2={(hash2.fi+((hash3.fi+mod1-hash4.fi)%mod1)*pw1[n-i])%mod1,(hash2.se+((hash3.se+mod2-hash4.se)%mod2)*pw2[n-i])%mod2};
        if(k1==k2){
            cout<<flag<<" "<<flag+i-1<<"\n";return ;
        }
    }
    string b="~";
    for(int i=m-flag+1;i>=flag;i--)b+=s[i];
    n=b.size()-1;
    hash1={0,0},hash2={0,0};
    for(int i=1;i<=n;i++){
        puu temp=gethash(b[i]);
        hash1.fi=(hash1.fi+temp.fi*pw1[i-1]%mod1)%mod1;
        hash1.se=(hash1.se+temp.se*pw2[i-1]%mod2)%mod2;
        hash2.fi=(hash2.fi+temp.fi*pw1[n-i]%mod1)%mod1;
        hash2.se=(hash2.se+temp.se*pw2[n-i]%mod2)%mod2;
    }
    hash3={0,0},hash4={0,0};
    for(int i=1;i<n;i++){
        puu temp=gethash(b[i]);
        hash3.fi=(hash3.fi+temp.fi*pw1[i-1]%mod1)%mod1;
        hash3.se=(hash3.se+temp.se*pw2[i-1]%mod2)%mod2;
        hash4.fi=(hash4.fi*base%mod1+temp.fi)%mod1;
        hash4.se=(hash4.se*base%mod2+temp.se)%mod2;
        puu k1={(hash1.fi+hash4.fi+mod1-hash3.fi)%mod1,(hash1.se+hash4.se+mod2-hash3.se)%mod2};
        puu k2={(hash2.fi+((hash3.fi+mod1-hash4.fi)%mod1)*pw1[n-i])%mod1,(hash2.se+((hash3.se+mod2-hash4.se)%mod2)*pw2[n-i])%mod2};
        if(k1==k2){
            cout<<m-flag-i+2<<" "<<m-flag+1<<"\n";return ;
        }
    }
    cout<<-1<<" "<<-1<<"\n";
}

难度上来了,很可惜有战犯没出数学题。

C. Potion(hard version)

题面:

​ 给出a,b,x,y。问能否用刻度为a/(a+b)的量筒通过盛水倒水,使得量筒中药水的浓度为x/(x+y)。

数据范围:

​ a,b,x,y均为[1,1e18]。

解法:

​ 首先,我们将ab,xy,处理成互质形式。为表述方便,我们设c=a+b。设有n+1次倒水,第一次占比例为\((a/c)^n\),剩下的第i次比例为\((b*a^{n+1-i})/c^{n+2-i}\),然后我们将他们求和,表示成\((a^n+b*\sum_{i=1}^{n}a^{n-i}*c^{i-1})/c^{n}\),然后这个等于\(x/(x+y)\)。

​ 做完了以上操作,下面我们面对的问题就是,能否从\(a^{n-i}*c^{i-1}\)中选出来某些子集,使得他们的和等于现在的m。i的范围是从1到n。于是我们只需要看当前的m是否能被a整除。如果能,那么i=1是不能选的,因为a与c互质,否则就必选。于是我们把m进行相应的改变,即如果不能整除就减去\(a^{n-1}\),如果能整除就不减,然后再看能否被c整除,能则除以c。昨晚以上操作,我们发现这个问题转化成了一个子问题,此时n等于n-1。然后我们只需要一遍遍去递归求解即可。

​ 但这样说还是感觉有十分甚至九分的抽象,因为n其实是我们假设出来的。下面给出喂饭级别的教程。

​ 0,当x和y有一方为0的时候,结束。

​ 1,观察是否有\((x+y)\mid{c}\) 。若\((x+y)\nmid{c}\),那么无解。这一条的依据是\(x+y=(a^n+b*\sum_{i=1}^{n}a^{n-i}*c^{i-1})/c^{n}\)。即倒完水后,稀释的分母为c。

​ 2,然后观察x是否能被a整除,若能,则x除以a,y则等于总的减去当前的x。若不能,y除以a,x等于总的减去当前的x。

代码:
void solve(){
    ll a,b,x,y;cin>>x>>y>>a>>b;
    int cnt=1;
    ll g=__gcd(a,b);a/=g,b/=g;
    g=__gcd(x,y);x/=g,y/=g;
    ll c=a+b;
    while(x&&y){
        if(x>y)swap(x,y);
        cnt++;
        ll z=x+y;
        if(z%c){cout<<-1<<"\n";return ;}
        z/=c;
        if(x%a==0){
            x/=a;y=z-x;
        }
        else if(y%a==0){
            y/=a;x=z-y;
        }
        else{cout<<-1<<"\n";return ;}
    }
    cout<<cnt<<"\n";
}

C. Potion(hard version)

题面:

​ 给两个数组a,b和一个正整数x,从1到n如果bi等于0,那么x=x&a[i],否则x=x|a[i]。给出q次询问,每次询问给出一个x一个k,k表示最多可以反转k个bi,要求给出每次询问的最大值。

数据范围:

​ n,q均为[1,2e5],ai为[1,\(2^{30}\))。

解法:

​ 本题的关键在于,要看出来反转最后k个bi是最优的,下面给出证明:

​ 假设i<j,然后我们对于ai,aj的每一个二进制为分开考虑,那么

​ 1,ai=aj:此时无论反转哪个,影响都一样。

​ 2,ai=1,aj=0:如果反转i而不反转j,是没有意义的,所以必须要先保证j是反转的。

​ 3,ai=0,aj=1:反转j后,无论i反转不反转,均没有影响。

​ 证明完毕后,那么我们只需要用两个前缀和与一个后缀和,来维护k次反转的结果,可以做到\(O(1)\)查询。

代码:
void solve(){
    int n,m;cin>>n>>m;
    vector<int>a(n+1);
    vector<int>b(n+1);
    vector<int>pre(n+2);vector<int>c(n+2);vector<int>suf(n+2);
    c[0]=(1ll<<30)-1ll;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++){
        cin>>b[i];
        if(b[i]){pre[i]=pre[i-1]|a[i];c[i]=c[i-1];}
        else {pre[i]=pre[i-1]&a[i];c[i]=c[i-1]&a[i];}
    }
    vector<int>pos(n+2);
    int cnt=0;
    pos[0]=n+1;
    for(int i=n;i>=1;i--){
        suf[i]=suf[i+1]|a[i];
        if(!b[i])cnt++;
        pos[cnt]=i;
    }
    while(m--){
        int x,k;cin>>x>>k;        k=min(k,cnt);
        int idx=pos[k];
        cout<<(x&c[idx-1]|pre[idx-1]|suf[idx])<<"\n";
    }
}

先写到这吧,后面的再补,主要是tmd写了别的几篇的,忘保存了,烦死了,等心情好了再写。

标签:cnt,idx,int,void,CCPC,cin,seg,2022,湖北省
From: https://www.cnblogs.com/shi5/p/18023360

相关文章

  • 李宏毅《机器学习》总结 - 2022 HW8(Anomaly Detection、ResNet) Strong Baseline
    重新学习了一下ResNet。。这作业平均一跑就是3、4个小时题目大意是让你做异常检测(anomalydetection),即给你一些正常的图片,再让你测试图片是正常的还是异常的(可以理解为2分类问题,只不过其中一个类别是无限大的)代码:https://www.kaggle.com/code/skyrainwind/hw8-anomaly-detec......
  • windows server 2019/2022安装WSUS更新服务器配置System.Runtime.InteropServices.COM
    现象: 2024-02-1814:41:10Postinstallstarted2024-02-1814:41:10Detectedroleservices:Api,UI,WidDatabase,Services2024-02-1814:41:10Start:LoadSettingsFromXml2024-02-1814:41:10Start:GetConfigValuewithfilename=UpdateServices-Services.xmlit......
  • 互联网信息服务算法推荐管理规定 (全文学习)2022年01月04日 本规定自2022年3月1日起施
    互联网信息服务算法推荐管理规定第一章总则第一条 为了规范互联网信息服务算法推荐活动,弘扬社会主义核心价值观,维护国家安全和社会公共利益,保护公民、法人和其他组织的合法权益,促进互联网信息服务健康有序发展,根据《中华人民共和国网络安全法》、《中华人民共和国数据安全法......
  • 上海市促进 人工智能产业发展条例 (全文学习)2022年10月01日 本条例自2022年10月1日
    上海市促进人工智能产业发展条例(2022年9月22日上海市第十五届人民代表大会常务委员会第四十四次会议通过)第一章 总则  第一条 为了促进人工智能产业高质量发展,强化新一代人工智能科技创新策源功能,推动人工智能与经济、生活、城市治理等领域深度融合,打造人工智能世界级产业......
  • 【专题】2022数字化转型指数年度报告PDF合集分享(附原数据表)
    原文链接:https://tecdat.cn/?p=33471原文出处:拓端数据部落公众号数字化转型指数报告2022合集根据“基础设施-平台-应用”三层指标体系,对全国300余个城市、10余个行业的数字化发展规模进行了评估。该报告提供了覆盖全国范围的季度数字化转型指数,为各行各业推进数字化转型提供了有益......
  • 在 Visual Studio 2022 中创建一个类似于旧版本 Visual Studio 中的 Win32 Console Ap
    以下内容来自AI的回答,实测有效在VisualStudio2022中创建一个项目,其自动生成的源文件内容包含#include"stdafx.h"和使用_tmain作为入口点,意味着你需要创建一个基于Windows的传统控制台应用程序,这通常与旧版本的VisualStudio(如VisualStudio2005或更早)和使用预......
  • Unity 2022.3.20f1新功能,异步实例化预制体Object.InstantiateAsync
    今天查看Unity2022.3.20f1更新日志,发现新增了个异步实例化的功能,这个功能解决了Unity历史上实例化预制体卡顿的痛点,简直不要太爽。具体的API文档请点击跳转。做了个简单的实例化测试,实例化500*500个Cube,耗时9.2s。实例化过程之间不会卡顿,可以做其他事情,即便是在重度游戏加载场......
  • P8784 [蓝桥杯 2022 省 B] 积木画
    原题链接太妙了,请移步题解区,有用数学归纳法做的,也有用找规律做的L型积木一定是成对出现的code#include<bits/stdc++.h>usingnamespacestd;constintmod=1e9+7;longlongdp[10000005]={0};intmain(){intn;cin>>n;dp[0]=1;dp[1]=1;dp[2]=2;......
  • Windows Server 2022 新的服务管理 API 提供了更多的选项和功能,可以更灵活地进行服务
    sc 命令是Windows操作系统自带的一种命令行实用程序,用于创建、删除、启动、停止以及配置Windows服务。通过 sc 命令,您可以直接将可执行文件注册为服务,而不需要第三方工具的帮助。sc 命令提供了丰富的选项,如启动类型、依赖关系、服务描述等。instsrv 和 srvany 是两个......
  • 2022年全年回顾
    书接2021年全年回顾,继续参与部门的新产品。个人收获学习incredibuild的使用方法,不过经过评估和实战,没有在产品中使用。使用了各种方式改善流水线的构建效率和体验,对提升开发团队的效率有一定帮助。按照公司的发布流程,处理开源软件的漏洞,学习并掌握了很多开源软件的构建方法,输......