首页 > 其他分享 >2020年河南省CCPC 题解

2020年河南省CCPC 题解

时间:2023-03-14 19:44:57浏览次数:48  
标签:int 题解 CCPC read 2020 ans Problem YES mod

2020年河南省CCPC题解

Problem A. 班委竞选

  设 ax 为第 x 类班干部最大票数。从小到大枚举学号i,若新x>ax则更新ax并且记录i为ansx的答案

void solve(){
    int n=read(),m=read();
    for(int i=1;i<=n;i++){
        int x=read(),y=read();
        if(a[x]<y){
            a[x]=y;
            ans[x]=i;
        }
    }
    for(int i=1;i<=m;i++){
        cout<<ans[i]<<" ";
    }
    //puts(ans>0?"YES":"NO");
    //puts(ans>0?"Yes":"No");
}

 

 

Problem B. 广告投放

  本题的朴素dp思路很好想,但是空间上是O(nm),时间上也是O(nm)。

  想到[n/i]的取值只有O(√n)种,然后就预处理出取值可能(赛后知道 这是数论分块),之后的转移方程很好想

void solve(){
    int n=read(),m=read();
    for(int i=1;i<=n;i++){
        p[i]=read();
    }
    for(int i=1;i<=n;i++){
        d[i]=read();
    }
    int cnt=0;
    for(int i=1;i<=m;i++){
        if(v[m/i]==0) mayp[++cnt]=m/i,v[m/i]=1;
    }
    mayp[0]=0;
    sort(mayp,mayp+cnt+1);
    for(int i=1;i<=n;i++){
        for(int j=0;j<=cnt;j++){
            dp[mayp[j]/d[i]]=max(dp[mayp[j]]+p[i]*mayp[j],dp[mayp[j]/d[i]]);
        }
    }
    int ans=0;
    for(int i=0;i<=cnt;i++){
        ans=max(ans,dp[mayp[i]]);
    }
    cout<<ans<<endl;
    //puts(ans>0?"YES":"NO");
    //puts(ans>0?"Yes":"No");
}

 

Problem C. 我得重新集结部队

  纯模拟 但是很简单

struct node{
    int p,x,y,h,r,atk,li;
}a[N];
void solve(){
    int n=read();
    for(int i=1;i<=n;i++){
        a[i].p=read();
        if(a[i].p==1){
            a[i].x=read();
            a[i].y=read();
            a[i].h=read();
            a[i].li=1;
        }else {
            a[i].x=read();
            a[i].y=read();
            a[i].atk=read();
            a[i].r=read();
            a[i].li=1;
            int rx=-1,ry=-1,ans=INF;
            for(int j=1;j<i;j++){
                if(a[j].p==1&&a[j].li==1){
                    int temp=(a[j].x-a[i].x)*(a[j].x-a[i].x)+(a[j].y-a[i].y)*(a[j].y-a[i].y);
                    if(temp<ans){
                        ans=temp;
                        rx=a[j].x;
                        ry=a[j].y;
                    }
                }
            }
            int out=0;
            for(int j=1;j<i;j++){
                if(a[j].p==1&&a[j].li==1&&(rx-a[j].x)*(rx-a[j].x)+(ry-a[j].y)*(ry-a[j].y)<=a[i].r*a[i].r){
                    a[j].h-=3*a[i].atk;
                    if(a[j].h<=0)a[j].li=0;
                    else out=1;
                }
            }
            if(out==1)a[i].li=0;
        }
    }

    for(int i=1;i<=n;i++){
        puts(a[i].li==1?"Yes":"No");

    }
    //puts(ans>0?"YES":"NO");
}

 

Problem E. 发通知

  我认为还是个小模拟,题目本身不难,但是在区间里容易想偏(至少我是这样的额)

struct node{
    int poi,op,w;
    friend bool operator<(const node&a,const node&b){
        return a.poi<b.poi;
    }
}a[N];
void solve(){
    int n=read(),k=read();
    int cnt=0;
    for(int i=1;i<=n;i++){
        int x=read(),y=read(),z=read();
        a[cnt++]={x,0,z};
        a[cnt++]={y+1,1,z};
    }
    sort(a,a+cnt);
    int num=0,sum=0,ans=-1;
    for(int i=0;i<cnt;i++){
        int poi=a[i].poi,w=a[i].w,op=a[i].op;
        if(!op){
            num++;
            sum^=w;
            if(num>=k&&a[i+1].poi!=poi){
                ans=max(ans,sum);
            }
        }else{
            num--;
            sum^=w;
            if(num>=k&&a[i+1].poi!=poi){
                ans=max(ans,sum);
            }
        }
    }
    if(ans>=0)cout<<ans<<endl;
    else cout<<-1<<endl;
    //puts(ans>0?"YES":"NO");
    //puts(ans>0?"Yes":"No");
}

 

Problem I. 太阳轰炸

  本题思路很清楚 将题目的模型最后转化为求一个O(n)长度的组合数的和

  又因为要求逆元 自然的想到预处理阶乘和阶乘的逆元

int fac[N],inv[N];
inline int combination(int n,int k){
    return fac[n]*inv[k]%mod*inv[n-k]%mod;
}
int qmi(int m, int k, int p)
{
    int res = 1 % p, t = m;
    while (k)
    {
        if (k&1) res = res * t % p;
        t = t * t % p;
        k >>= 1;
    }
    return res;
}
void solve(){
    int n=read(),r1=read(),r2=read(),r=read(),a=read(),h=read();
    int k=(h-1)/a+1;
    if(k>n){
        cout<<0<<endl;
        return;
    }
    if(r2<=(r1+r)){
        cout<<1<<endl;
        return ;
    }
    
    fac[0]=1;
    for(int i=1;i<=n+1;i++) fac[i]=fac[i-1]*i%mod;
    inv[n+1]=qmi(fac[n+1],mod-2,mod);
    for(int i=n;i>=0;i--) inv[i]=inv[i+1]*(i+1)%mod;

    int rn=qmi(r2*r2%mod,mod-2,mod);
    int p=(r1+r)*(r1+r)%mod*rn%mod;
    int q=(r2*r2%mod-(r1+r)*(r1+r)%mod+mod)%mod*rn%mod;
      
    int pk=qmi(p,k,mod);
    int qnk=qmi(q,n-k,mod);
      
    LL res=0;
    for(int i=k;i<=n;i++)
    {
        res=res+combination(n,i)*pk%mod*qnk%mod;
        res%=mod;
        pk=(LL)pk*p%mod;
        qnk=(LL)qnk*qmi(q,mod-2,mod)%mod;
    }

    printf("%lld\n",res);
    //puts(ans>0?"YES":"NO");
    //puts(ans>0?"Yes":"No");
}
}

 

Problem J. 二进制与、平方和

  题目一眼线段树 但是阅历太浅 根本想不到怎么做

  modify的时候如果与上目标值对结果无影响就return 因为只有原值1&目标值0的时候才会有影响 显然每个位置最多变化loga 乍一看时间复杂度是O(nlognloga) 但是实际上O(n(logn+loga))

  网上的代码都千遍一律 线段树里有一个25的数组 时间效率低 codeforces上至少要1900ms 这份只要400ms 

int n, q, a[N];
 
struct Info{
    int sum, orsum;
}seg[N << 2];
 
Info operator + (const Info &a, const Info &b){
    Info c;
    c.orsum = a.orsum | b.orsum;
    c.sum = a.sum + b.sum;
    return c;
}
 
void up(int id){
    seg[id] = seg[id << 1] + seg[id << 1 | 1];
}
void build(int id, int l, int r){
    if(l == r){
        seg[id].orsum = a[l] % mod;
        seg[id].sum = (a[l] * a[l]) % mod;
        return;
    }
    int mid = (l + r) >> 1;
    build(id << 1, l, mid);
    build(id << 1 | 1, mid + 1, r);
    up(id);
}
 
void modify(int id, int l, int r, int ql, int qr, int val){
    if((seg[id].orsum & val) == seg[id].orsum) return;
    if(l == r){
        seg[id].orsum = seg[id].orsum & val;
        seg[id].sum = (seg[id].orsum * seg[id].orsum) % mod;
        return;
    }
    int mid = (l + r) >> 1;
    if(qr <= mid){
        modify(id << 1, l, mid, ql, qr, val);
    }else if(ql> mid){
        modify(id << 1 | 1, mid + 1, r, ql, qr, val);
    }else{
        modify(id << 1, l, mid, ql, mid, val);
        modify(id << 1 | 1, mid + 1, r, mid + 1, qr, val);
    }
    up(id);
}
 
 
int query(int id, int l, int r, int ql, int qr){
    if(l == ql && r == qr){
        return seg[id].sum;
    }
    int mid = (l + r) >> 1;
    if(qr <= mid){
        return query(id << 1, l, mid, ql, qr);
    }else if(ql > mid){
        return query(id << 1 | 1, mid + 1, r, ql, qr);
    }else{
        return query(id << 1, l, mid, ql, mid) + query(id << 1 | 1, mid + 1, r, mid + 1, qr);
    }
}
signed main(){
    cin >> n;
    for(int i = 1; i <= n ; i ++) cin >> a[i];
    build(1, 1, n);
    cin >> q;
    while(q --){
        int ty, l, r;
        cin >> ty >> l >> r;
        if(ty == 1){
            int x;
            cin >> x;
            modify(1, 1, n, l, r, x);
        }else{
            cout << query(1, 1, n, l, r)% mod << endl;
        }
    }
}

 

标签:int,题解,CCPC,read,2020,ans,Problem,YES,mod
From: https://www.cnblogs.com/edgrass/p/17216062.html

相关文章

  • P5200 [USACO19JAN]Sleepy Cow Sorting G 题解
    前言:教练要求写的,于是过来补发题解。题目传送门分析容易发现后缀如果是上升的那么就不用动,让前面的通过移动插进来就可以了,第一个答案就是\(n\)减去最长上升后缀的长......
  • CF1788D Moving Dots 题解
    可能更好的阅读体验题目传送门题目翻译题目解析考虑怎样才能产生贡献,显然对于留下的相邻的\(l,r\),需要让\(l\)向右,\(r\)向左即可产生\(1\)的贡献。接下来就是考......
  • [整理]NOIP2021 题解
    T1秒了,直接写一个线性筛一样的东西即可。constintN=10000010;intT,x;boolok[N];intnxt[N];ilvoidInit(){for(inti=1;i<N;i++){if(ok[i])continue;......
  • 【题解】P6071 『MdOI R1』Treequery
    题目描述给定一棵\(n\)个点的无根树,边有边权。令\(E(x,y)\)表示树上\(x,y\)之间的简单路径上的所有边的集合,特别地,当\(x=y\)时,\(E(x,y)=\varnothing\)。你需......
  • docker安装笔记及常见问题解决
    1.yum安装gcc相关环境yum-yinstallgccyum-yinstallgcc-c++2.卸载旧版本(非必要)yumremovedocker\docker-client\docker-client-latest\doc......
  • 由于找不到 visa32.dll问题解决办法
    由于找不到visa32.dll,无法继续执行代码。重新安装程序可能会解决此问题。 金山官网下载https://www.ijinshan.com/filerepair/visa32.dll.shtml由于找不到NiViSv32.d......
  • 【题解】[HEOI2013]Segment(李超树)
    [HEOI2013]Segment题目分析:是李超线段树的板子题,在这里就稍微提一嘴李超线段树吧。其实李超线段树就是用来解决插入线段,查询\(x=k\)时纵坐标的最大值的。对于李超线......
  • [BUUCTF]Reverse-[BJDCTF2020]JustRE
      进去之后直接看字符串窗口,发现一个疑似flag的,点进去查看    我的妈耶!良心啊,直接把flag给我们了,呜呜呜呜,真的好少见这种淳朴的出题人!!!BJD{1999902069a4579......
  • P7728 旧神归来 题解
    日常生活:写多项式——写多项式题解——颓——写多项式——写多项式题解——颓——……最近真的降智。大水题切不动。#查询gtm1514精神状态题解好像挺清新的。首先我......
  • [转]mysql问题解决SELECT list is not in GROUP BY clause and contains nonaggregate
    原文地址:mysql问题解决SELECTlistisnotinGROUPBYclauseandcontainsnonaggregatedcolumn-慕尘-博客园(cnblogs.com)今天在Ubuntu下的部署项目,发现一些好......