Codeforces Round 895 (Div. 3)

A.TwoVessels

一开始我以为那个 c 桶只能装满,看了好久。
范围内的任意容量都可以取的话,那么只要看需要转移多少量,然后看需要多少次。

void solve(){
    int n=read(),m=read(),k=read();
    double nd=abs(n-m)*1.0/2;
    int ans=ceil(nd/k);
    cout<<ans<<'\n';
    //puts(ans>0?"YES":"NO");
    //puts(ans>0?"Yes":"No");
}

B.TheCorridororThereandBackAgain

计算每个房间走过之后能最多向后走几个房间,向后遍历的时候取最小值。

void solve(){
    int n=read();
    vector<int>a(10000,inf);
    for(int i=1;i<=n;i++){
        int x=read(),y=read();
        a[x]=min((y-1)/2,a[x]);
    }
    int now=inf;
    for(int i=1;i<=10000&&i<=now;i++){
        now=min(a[i]+i,now);
    }
    cout<<now<<'\n';
    //puts(ans>0?"YES":"NO");
    //puts(ans>0?"Yes":"No");
}

C.NoncoprimeSplit

如果一个数能被整除,就可以被分成这么多份,那么只要每份的个数大于 1 就可以做到题目要求的 gcd1

void solve(){
    int l=read(),r=read();
    for(int i=l;i<=r;i++){
        int x=i;
        for(int j=2;j*j<=x;j++){
            if(x%j==0){
                cout<<x/j<<" "<<x-x/j<<'\n';
                return ;
            }
        }
    }
    cout<<-1<<'\n';
    //puts(ans>0?"YES":"NO");
    //puts(ans>0?"Yes":"No");
}

D.PlusMinusPermutation

肯定把最大值放在加的地方,最小值放在减的地方,不知道知道的只有放多少个。
显然能起作用的加数是 n/xn/lcm(x,y) ,减数同理。
知道个数之后只需要求和即可。

int get_sum(int x,int y){
    return (x+y)*(y-x+1)/2;
}
int gcd(int a, int b){
    return b ? gcd(b, a % b) : a;
}

void solve(){
    int n=read(),a=read(),b=read();
    int g=a*b/(gcd(a,b));
    b=n/b-n/g;
    a=n/a-n/g;
    int ans=get_sum(n-a+1,n);
    ans-=get_sum(1,b);
    cout<<ans<<'\n';
    //puts(ans>0?"YES":"NO");
    //puts(ans>0?"Yes":"No");
}

E.DataStructuresFan

每次修改都是直接异或上区间和就行了,那么修改和查询的复杂度都是 O(1)

int sum[N],a[N];
void solve(){
    int n=read(),ans0=0,ans1=0;
    for(int i=1;i<=n;i++){
        a[i]=read();
    }
    string s;
    cin>>s;
    s=' '+s;
    for(int i=1;i<=n;i++){
        if(s[i]=='0')ans0^=a[i];
        else ans1^=a[i];
    }
    for(int i=1;i<=n;i++){
        sum[i]=sum[i-1]^a[i];
    }
    int q=read();
    while(q--){
        int op=read();
        if(op==1){
            int x=read(),y=read();
            int chg=sum[y]^sum[x-1];
            ans1^=chg;
            ans0^=chg;
        }else{
            int x=read();
            if(x==0)cout<<ans0<<' ';
            else cout<<ans1<<' ';
        }
    }
    cout<<'\n';
    //puts(ans>0?"YES":"NO");
    //puts(ans>0?"Yes":"No");
}

F.SellingaMenagerie

如果把入度为 0 的点不断删掉,那么将会变成一个基环图,而且先删掉这样的点肯定是最优的。
对于一个环,可以有一个点被计算一次,其他点计算两次,显然选择最小的点计算一次,用优先队列跑一下。

void solve(){
    int n=read();
    vector<int>a(n+1),r(n+1),o(n+1),fa(n+1),vis(n+1);
    vector<int>res;
    for(int i=1;i<=n;i++){
        int x=read();
        fa[i]=x;
        r[x]++;
        o[i]++;
    }
    for(int i=1;i<=n;i++)a[i]=read();
    int ans=0;
    for(int i=1;i<=n;i++){
        if(r[i]==0&&vis[i]==0){
            r[fa[i]]--,ans+=a[i],vis[i]=1,res.push_back(i);
            int nex=fa[i];
            while(r[nex]==0){
                r[fa[nex]]--,ans+=a[nex],vis[nex]=1,res.push_back(nex);
                nex=fa[nex];
            }
        }else pq.push(make_pair(a[i],i));
    }

    while(pq.size()){
        int x=pq.top().first,y=pq.top().second;
        pq.pop();
        if(vis[y]){
            continue;
        }
        ans+=x;
        int nex=fa[y];
        while(vis[nex]==0){
            ans+=a[nex]*2;
            res.push_back(nex);
            vis[nex]=1;
            nex=fa[nex];
        }
    }    for(auto x:res){
        cout<<x<<" ";
    }
    cout<<'\n';
    //puts(ans>0?"YES":"NO");
    //puts(ans>0?"Yes":"No");
}

G.ReplaceWithProduct

首先显然的,左右两侧的 1 都不应在乘的区间里。后面所说的不再考虑这些数字。
剩下的数字如果计算乘积可能用 longlong 存不下,那么会发现,如果乘积一旦大于1e9就说明存在平凡解,即所有余下的数字。否则就说明不为 1 的点只有 logn1e9 个,这时候穷举所有情况即可。

int a[N];
void solve(){
    int n=read(),sum=0;
    for(int i=1;i<=n;i++){
        a[i]=read();
        sum+=a[i];
    }
    int l=1,r=n;
    for(int i=1;i<=n&&l<r;i++){
        if(a[i]==1)l++;
        else break;
    }
    for(int i=n;i>=1&&r>l;i--){
        if(a[i]==1)r--;
        else break;
    }
    int allji=1;
    for(int i=l;i<=r;i++){
        allji*=a[i];
        if(allji>=1e9){
            cout<<l<<" "<<r<<'\n';
            return ;
        }
    }
    vector<int>vec;
    for(int i=1;i<=n;i++){
        if(a[i]>1)vec.push_back(i);
    }
    int ansl=1,ansr=1,ans=sum;
    for(int i=0;i<vec.size();i++){
        int l=vec[i],res=1,s=0;
        for(int j=i;j<vec.size();j++){
            int r=vec[j];
            res*=a[r];
            s+=a[r]-1;
            int v=sum-(r-l+1)-s+res;
            if(v>ans){
                ans=v;
                ansl=l;
                ansr=r;
            }
        }
    }
    cout<<ansl<<" "<<ansr<<'\n';
    //puts(ans>0?"YES":"NO");
    //puts(ans>0?"Yes":"No");
}

本文作者:EdGrass

本文链接:https://www.cnblogs.com/edgrass/p/17686461.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   EdGrass  阅读(141)  评论(1编辑  收藏  举报
   
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 影子 岛屿心情
影子 - 岛屿心情
00:00 / 00:00
An audio error has occurred.

作词 : 张龙/史维旭/刘博宽/格桑咸俊

作曲 : 张龙/史维旭/刘博宽/格桑咸俊

编曲:岛屿心情

总是迷恋水中倒映的自己

总是迷恋水中倒映的自己

总会为你穿上漂亮的外衣

在云端坠落后不堪一击

却仍旧搭起虚幻的云梯

直到没有什么能使你满意

直到没有什么能使你满意

直到那些伤口不再能痊愈

你早已失去了爱的能力

这里的风景还能有什么意义

这是我今生的

这是我今生的

这是我仅剩的

要为你准备多少才将我抛弃

我让你娱乐做你的工具

你可以轻松毁掉一切并嫁祸于我

你可以轻松毁掉一切并嫁祸于我

在这间屋子里我什么都不能说

我爱啊恨啊醉啊

你荡啊荡啊追啊

我是你的影子

我是你的影子

我透过影子追逐你

我透过影子追逐你

我透过影子追逐你

我透过影子追逐你

我透过影子追逐你

我透过影子追逐你

(我早已)

我透过影子追逐你

(看穿了你)

我透过影子追逐你

(我早已)

我透过影子追逐你

(看穿了你)

我透过影子追逐你

(我早已)

我透过影子追逐你

(看穿了你)

我透过影子追逐你

(我不再)

我透过影子追逐你

(不再怕你)

制作人:王大治

制作人:王大治

录音师:杨森 B2

混音师:王大治

录音棚:时音唱片

母带后期:时音唱片