CF558

CF558A

可以发现,最大值就是取完两侧数量min之后剩下的再取一个。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline
#define endl '\n'
#define gc cin.get
#define pc cout.put
const int N=2e3+5;
const int M=1e6+5;
const int inf=0x7fffffff;
const int mod=997;
const int base=13131;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,ans;
vector<pair<int,int>>a,b;
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    n=read();
    for(int i=1;i<=n;i++){
        int x=read(),y=read();
        if(x<0)a.push_back({x,y});
        else b.push_back({x,y});
    }
    sort(a.begin(),a.end(),greater<pair<int,int>>());
    sort(b.begin(),b.end());
    for(int i=0;i<=(int)min(a.size(),b.size())-1;i++)
        ans+=a[i].second+b[i].second;
    if(a.size()>b.size())ans+=a[b.size()].second;
    else if(a.size()<b.size())ans+=b[a.size()].second;
    cout<<ans<<endl;
    return 0;
}

CF558B

注意到至于很小,那么我们对于开个桶,记录每个值出现次数和最左/右的位置即可。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline
#define endl '\n'
#define gc cin.get
#define pc cout.put
const int N=1e6+5;
const int M=1e6+5;
const int inf=0x7fffffff;
const int mod=997;
const int base=13131;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,ans,t[N],l[N],r[N],ma,mi(inf),resl,resr;
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    n=read();
    for(int i=1;i<=n;i++){
        int x=read();
        t[x]++;ma=max(ma,t[x]);
        if(!l[x])l[x]=i;r[x]=i;
    }
    for(int i=1;i<=1e6;i++)
        if(t[i]==ma){
            if(r[i]-l[i]<mi){
                mi=r[i]-l[i];
                resl=l[i],resr=r[i];
            }
        }
    cout<<resl<<' '<<resr<<endl;
    return 0;
}

CF558C

找了半天性质,突然发现值域1e5。不看英文题面的后果
可以发现,类似这种乘2或者除以2的操作很像线段树节点的编号。
所以我们把这个序列放到二叉树上,那么操作分别对应儿子找父亲/父亲找左儿子。
换根dp即可。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline
#define endl '\n'
#define gc cin.get
#define pc cout.put
const int N=1e6+5;
const int M=1e6+5;
const int inf=0x7fffffff;
const int mod=997;
const int base=13131;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,a[N],t[N],res(inf),ans,dep[N],rt,f[N];
inl void dfs1(int x,int d){
    if(x>1e5)return;f[x]=t[x];
    dfs1(x<<1,d+1);
    dfs1(x<<1|1,d+1);
    t[x]+=t[x<<1]+t[x<<1|1];
    if(!rt&&t[x]==n)rt=x;
}
inl void dfs2(int x,int d){
    if(x>1e5)return;
    ans+=d*f[x];
    dfs2(x<<1,d+1);
    dfs2(x<<1|1,d+1);
}
inl void dfs3(int x,int ans){
    res=min(res,ans);
    if(x>1e5)return;
    ans+=n-2*t[x<<1];
    dfs3(x<<1,ans);
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    n=read();
    for(int i=1;i<=n;i++)t[read()]++;
    dfs1(1,0);ans=0;dfs2(rt,0);dfs3(rt,ans);
    cout<<res<<endl;
    return 0;
}

CF558E

线段树经典操作。
开26棵线段树直接维护即可。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline
#define endl '\n'
#define gc cin.get
#define pc cout.put
const int N=1e5+5;
const int M=1e6+5;
const int inf=0x7fffffff;
const int mod=997;
const int base=13131;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,q,a[N];
struct node{
    int a[27];
    friend node operator+(node a,node b){
        for(int i=1;i<=26;i++)a.a[i]+=b.a[i];
        return a;
    }
};
inl void emptynode(node &x){for(int i=1;i<=26;i++)x.a[i]=0;}
struct segmentree{
    node s[N<<2];int tag[N<<2];
    #define ls k<<1
    #define rs k<<1|1
    #define mid (l+r>>1)
    inl void pushup(int k){s[k]=s[ls]+s[rs];}
    inl void adt(int k,int l,int r,int c){
        emptynode(s[k]);s[k].a[c]=r-l+1;
        tag[k]=c;
    }
    inl void pushdown(int k,int l,int r){
        if(!tag[k])return;
        adt(ls,l,mid,tag[k]);adt(rs,mid+1,r,tag[k]);
        tag[k]=0;
    }
    inl void build(int k,int l,int r){
        if(l==r)return s[k].a[a[l]]++,void();
        build(ls,l,mid);build(rs,mid+1,r);
        pushup(k);
    }
    inl void modify(int k,int l,int r,int x,int y,int c){
        if(x<=l&&r<=y)return adt(k,l,r,c);
        pushdown(k,l,r);
        if(x<=mid)modify(ls,l,mid,x,y,c);
        if(y>mid)modify(rs,mid+1,r,x,y,c);
        pushup(k);
    }
    inl node query(int k,int l,int r,int x,int y){
        if(x<=l&&r<=y)return s[k];
        node ans;emptynode(ans);pushdown(k,l,r);
        if(x<=mid)ans=ans+query(ls,l,mid,x,y);
        if(y>mid)ans=ans+query(rs,mid+1,r,x,y);
        return ans;
    }
    inl void print(int k,int l,int r){
        if(l==r){
            for(int i=1;i<=26;i++)
                if(s[k].a[i])
                    return cout<<(char)(i+'a'-1),void();
        }
        pushdown(k,l,r);
        print(ls,l,mid);print(rs,mid+1,r);
    }
}SGT;
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    n=read();q=read();
    for(int i=1;i<=n;i++){
        char c;cin>>c;
        a[i]=c-'a'+1;
    }
    SGT.build(1,1,n);
    while(q--){
        int l=read(),r=read(),k=read();
        node a=SGT.query(1,1,n,l,r);
        if(k){
            for(int i=1;i<=26;i++)
                if(a.a[i])SGT.modify(1,1,n,l,l+a.a[i]-1,i),l+=a.a[i];
        }else
            for(int i=26;i;i--)
                if(a.a[i])SGT.modify(1,1,n,l,l+a.a[i]-1,i),l+=a.a[i];
    }
    SGT.print(1,1,n);
    return 0;
}
posted @ 2023-12-25 16:52  xiang_xiang  阅读(2)  评论(0编辑  收藏  举报