Codeforces Round #373 (Div. 2)

Codeforces Round #373 (Div. 2)

题目链接

https://codeforces.com/contest/719

 

A题题解

  • 题解:判断最后一天,若是0则UP,是15则DOWN. 若n是1且a[1]不是0或15则-1. 否则比较a[n]与a[n-1]即可.

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
# define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
//struct note{
//    int x ,y;
//}st[300000 + 10];
//set<ll> s1,s2; 
//ll a[300000 + 10][2];
int a[100];
int main(){
    IOS;
int n;
cin >> n;
 

for(int i = 1; i<= n ; i++){
    cin >> a[i];
    
}
if(n==1 && a[1] == 15){puts("DOWN"); return 0;}
if(n==1 && a[1] == 0){puts("UP"); return 0;}
if(n == 1) {
    puts("-1");
    return 0;
}
if(a[n] == 15 && a[n] > a[n-1]) 
{
puts("DOWN");
return 0;
}
if(a[n] == 0 && a[n-1] == 1) {
    puts("UP");
    return 0 ; 
}

if(a[n] > a[n-1])
puts("UP");
else
puts("DOWN");


    return 0; 
}
View Code

 

B题题解

  • 题意:一个只含有r和b的字符串,两种操作,1 交换字符串中任意两个元素的位置,2 把r替换为b,或者把b替换为r,输出把字符串转换为交替的序列需要的最小操作数
  • 思路:目标字符串只有两种情况,rbrbrbrb或者brbrbrbr,分别求出给定字符串向这两种字符串转换所需的操作次数,取最小即可,那么如何求转换所需的最小次数呢,遍历一遍即可,分别求出与目标字符串不同的r 和 b的个数,例如,给定字符串与目标字符串字符不相同的位置上r有6个,b有4个,那么可以交换操作4次,修改操作2次,共6次

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
# define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
//struct note{
//    int x ,y;
//}st[300000 + 10];
//set<ll> s1,s2; 
//ll a[300000 + 10][2];
string a;
int main(){
    IOS;
int n;
cin >> n;
cin >> a;
int x = 0 , y = 0;
for(int i = 0 ; i < a.size();i++){
    if(i % 2 == 0){
        if(a[i]!='r')
        x ++;        
    }
    else
    {
        if(a[i] != 'b')
            y++;
    }
}
int ans = 0;
ans = abs(x - y) + min(x,y);
x = y = 0;
for(int i = 0 ; i < a.size();i++){
    if(i % 2 != 0){
        if(a[i]!='r')
        x ++;        
    }
    else
    {
        if(a[i] != 'b')
            y++;
    }
}
ans = min(ans , abs(x - y) + min(x,y));
cout << ans << endl;
    return 0; 
}
View Code

 

C题题解

  • 题意:你有n次操作,可以让给定的这个数的小数位四舍五入,求这个数经过t次操作后最大是多少
  • 题解:小数位如果第一个小数位是>=5的情况下,整数位的个位就要+1,如果整数位是999这种情况就要变成1000
  • 为了使得经过变换后的数最大,我们先从小数位的最前面开始进位

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
# define IOS ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
//struct note{
//    ll x ,y;
//}st[300000 + 10];
//set<ll> s1,s2; 
//ll a[300000 + 10][2];
string s;
int main()
{
    int n,t;
    scanf("%d%d",&n,&t);
    cin>>s;
    int i=0;
    while(s[i]!='.')i++;
    while(i<n&&s[i]<'5')i++;
    if(i==n)
    {
        cout<<s<<endl;
        return 0;
    }
    i--;int len=0;
    while(t>0)
    {
        if(s[i]!='.')s[i]++;
        else{
            i--;len=i;
            while(i>=0&&s[i]=='9')s[i--]='0';
            if(i==-1)cout<<'1';
            else s[i]++;
            break;
        }
        if(s[i]<'5')
        {
            len=i;
            break;
        }
        else
        {
            len=i;
            i--;
        }
        t--;
    }
    for(int k=0;k<=len;k++)
        cout<<s[k];
    cout<<endl;
}
View Code

 

E题题解

  • 题意:给出n个数字,有m个询问,每个询问:

 

  • 1: 区间(l,r)内,每个数,增加c
  • 2:区间(l,r)内,查询对应的f(x)之和(f()指的是斐波那契数列)
  • 分析:我们可以用过,矩阵快速幂来快速求出对应的斐波那契数,那么我们可以用线段树维护一个区间乘法矩阵。

AC代码

#include <algorithm>
#include <cstring>
#include <string.h>
#include <iostream>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <cstdio>
#include <cmath>
 
#define N 60005
#define INF 0x3ffffff
 
using namespace std;
const int matX = 2;
typedef __int64 LL;
const int mod = 1e9+7;
const int maxn = 1e5 +10;
 
LL ans;
struct Matrix
{
    int n, m;
    LL a[matX][matX];
    Matrix() {}
    void init(int _n, int _m)
    {
        n = _n;
        m = _m;
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < n; j++) a[i][j] = 0;
        }
    }
    Matrix operator + (const Matrix &B)const
    {
        Matrix C;
        C.init(n,m);
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                C.a[i][j]=(a[i][j]+B.a[i][j])%mod;
        return C;
    }
    Matrix operator*(const Matrix &P)const
    {
        Matrix ret;
        ret.init(n,m);
        for(int i = 0; i < n; i++)
        {
            for(int k = 0; k < m; k++)
            {
                if(a[i][k])
                {
                    for(int j = 0; j < P.m; j++)
                    {
                        ret.a[i][j] = ((LL)a[i][k] * P.a[k][j] + ret.a[i][j]) % mod;
                    }
                }
            }
        }
        return ret;
    }
    Matrix operator^(const LL &P)const
    {
        LL num = P;
        Matrix ret, tmp = *this;
        ret.init(n,m);
        for(int i = 0; i < n; i++) ret.a[i][i] = 1;
        while(num)
        {
            if(num & 1) ret = ret * tmp;
            tmp = tmp * tmp;
            num >>= 1;
        }
        return ret;
    }
};
struct node
{
    int l,r;
    Matrix add,sum;
} s[maxn*4];
 
LL h[maxn];
void pushup(int x)
{
    int tmp=x*2;
    s[x].sum=s[tmp].sum+s[tmp+1].sum;
}
bool judge(Matrix x)
{
    for(int i=0;i<x.n;i++)
        for(int j=0;j<x.m;j++)
            if(x.a[i][j]) return false;
    return true;
}
 
void pushdown(int x)
{
    if(judge(s[x].add)) return;
    int tmp=x*2;
    if(judge(s[tmp].add)) s[tmp].add=s[x].add;//这里原本是加法的,但是我们要维护乘法,所以要变成乘
    else                                      //同时还要考虑原矩阵是0矩阵的情况
        s[tmp].add=s[tmp].add*s[x].add;
    if(judge(s[tmp+1].add)) s[tmp+1].add=s[x].add;
    else
        s[tmp+1].add=s[tmp+1].add*s[x].add;
    s[tmp].sum=s[x].add*s[tmp].sum;
    s[tmp+1].sum=s[x].add*s[tmp+1].sum;
    s[x].add.init(2,2);
}
void buildtree(int l,int r,int x)
{
    s[x].l=l;
    s[x].r=r;
    s[x].add.init(2,2);
    s[x].sum.init(2,2);
    if(r==l)
    {
        Matrix as;
        as.init(2,2);
        as.a[0][0]=1;
        as.a[0][1]=1;
        as.a[1][0]=1;
        s[x].sum.a[0][0]=1;
        s[x].sum=(as^(h[l]-1))*s[x].sum;
        return;
    }
    int tmp=x<<1;
    int mid=(l+r)/2;
    buildtree(l,mid,tmp);
    buildtree(mid+1,r,tmp+1);
    pushup(x);
}
 
void query(int l,int r,int x)
{
    if(s[x].l==l&&s[x].r==r)
    {
        ans+=s[x].sum.a[0][0];
        ans%=mod;
        return ;
    }
    pushdown(x);
    int mid=(s[x].l+s[x].r)/2;
    if(r<=mid) query(l,r,2*x);
    else if(l>=mid+1) query(l,r,2*x+1);
    else
    {
        query(l,mid,2*x);
        query(mid+1,r,2*x+1);
    }
}
 
void updata(int l,int r,Matrix c,int x)
{
    if(r<s[x].l||l>s[x].r) return;
    if(l<=s[x].l&&r>=s[x].r)
    {
        if(judge(s[x].add)) s[x].add=c;
        else
            s[x].add=c*s[x].add;
        s[x].sum=c*s[x].sum;
        return;
    }
    pushdown(x);
    int tmp=x*2;
    updata(l,r,c,tmp);
    updata(l,r,c,tmp+1);
    pushup(x);
}
int main()
{
    int n,m,l,r,q;
    LL c;
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++)
        scanf("%I64d",&h[i]);
    buildtree(1,n,1);
    while(m--)
    {
        scanf("%d",&q);
        if(q==1)
        {
            scanf("%d%d%I64d",&l,&r,&c);
            Matrix as;
            as.init(2,2);
            as.a[0][0]=1;
            as.a[0][1]=1;
            as.a[1][0]=1;
            as=as^c;
            updata(l,r,as,1);//这里要把数字预处理矩阵带入,不然会被卡常
        }
        else
        {
            scanf("%d%d",&l,&r);
            ans=0;
            query(l,r,1);
            printf("%I64d\n",(ans%mod+mod)%mod);
        }
    }
    return 0;
}
View Code

 

posted @ 2019-04-03 21:13  Agnel_Cynthia  阅读(173)  评论(0编辑  收藏  举报
Live2D