北京建筑大学2024年程序设计竞赛(同步赛)

A寿命修改icon-default.png?t=N7T8https://ac.nowcoder.com/acm/contest/85333/A

 前置知识:线段树区间修改区间查询

本题除了在某些青蛙寿命小于零时要标记为死亡以外,就是一道线段树裸题;

对于已死亡的青蛙,递归到叶子节点处理,由于递归深度为log n,所以最差情况下时间复杂度为O(n logn)

算法的总体复杂度为 O(mlog⁡(n)+nlog⁡(n))

#include<bits/stdc++.h>

#define ll long long
#define alls(x) x.begin(),x.end()
#define ull unsigned long long
#define lowbit(x) x&-x
#define lc p<<1
#define rc p<<1|1
#define PII pair<int,int>
#define vi vector<int>
using namespace std;
const int mod = 998244353;
const int N = 1e6 + 10;
const ll inf = 2e18;
struct node{
    int l,r;
    ll sum;
    int alive;
    ll lazy;
    ll minn;
}tr[N<<2];
int a[N];

void push_up(int p)
{
    tr[p].sum = tr[lc].sum + tr[rc].sum;
    tr[p].minn = min(tr[lc].minn,tr[rc].minn);
    tr[p].alive = tr[lc].alive + tr[rc].alive;
}
void push_down(int p)
{
    tr[lc].sum+=tr[lc].alive * tr[p].lazy;
    tr[rc].sum+=tr[rc].alive * tr[p].lazy;
    tr[lc].minn+=tr[p].lazy;
    tr[rc].minn+=tr[p].lazy;
    tr[lc].lazy += tr[p].lazy;
    tr[rc].lazy += tr[p].lazy;
    tr[p].lazy = 0;
}
void kill(int p) {
    if (tr[p].minn > 0)
        return;
    if (tr[p].l == tr[p].r){
        tr[p].sum = 0;
        tr[p].minn = inf;
        tr[p].alive = 0;
        return;
    }
    push_down(p);
    kill(lc);
    kill(rc);
    push_up(p);
}
void build(int p,int l,int r) {
    tr[p].l = l, tr[p].r = r;
    if (l == r){
        tr[p].sum = a[l];
        tr[p].alive = 1;
        tr[p].minn = a[l];
        tr[p].lazy = 0;
        return;
    }
    int mid = l+r>>1;
    build(lc,l,mid),build(rc,mid+1,r);
    push_up(p);
}
void update(int p,int l,int r,ll x)
{
    if(tr[p].l>=l && tr[p].r<=r)
    {
        tr[p].lazy+=x;
        tr[p].sum+=tr[p].alive * x;
        tr[p].minn+=x;
        kill(p);
        return;
    }
    push_down(p);
    int mid = tr[p].l + tr[p].r >> 1;
    if (l <= mid)
        update(lc, l, r, x);
    if (r > mid)
        update(rc, l, r, x);
    push_up(p);
}
ll query(int p,int l,int r)
{
    if(tr[p].l>=l && tr[p].r<=r)
    {
        return tr[p].sum;
    }
    push_down(p);
    int mid = tr[p].l + tr[p].r >> 1;
    ll ans = 0;
    if(l<=mid)
        ans+=query(lc,l,r);
    if(r>mid)
        ans+=query(rc,l,r);
    return ans;
}


void solve() {
    int n;
    cin >> n;
    int m;
    cin >> m;
    for(int i = 1;i<=n;i++)cin >> a[i];
    build(1,1,n);
    int op,l,r;
    ll x;
    while(m--)
    {
        cin >> op;
        if(op==1)
        {
            cin >> l >> r >> x;
            update(1,l,r,x);
        }
        else
        {
            cin >> l >> r;
            cout<<query(1,l,r)<<'\n';
        }
    }
}

int main() {
    cout << fixed << setprecision(6);
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    // cin >> _;
    while (_--)solve();
}

 

B因数之和

经典拆分因子,时间复杂度为O(nlogn)

最后对结果进行前缀和处理,实现O(1)查询;

#include<bits/stdc++.h>

#define ll long long
#define alls(x) x.begin(),x.end()
#define ull unsigned long long
#define lowbit(x) x&-x
#define lc p<<1
#define rc p<<1|1
#define PII pair<int,int>
#define vi vector<int>
using namespace std;
const int mod = 998244353;
const int N = 1e6 + 10;
int a[N];
int b[N];
const int M = 1e6;
void solve() {
    int n;
    cin >> n;
    for(int i = 1;i<=M;i++)
    {
        for(int j = i;j<=M;j+=i)
        {
            a[j]+=i;
        }
    }
    for(int i = 1;i<=M;i++)b[i] = b[i-1] + (a[i]>=2*i);
    int L,R;
    while(n--)
    {
        cin >> L >> R;
        cout<<b[R] - b[L-1]<<'\n';
    }
}

int main() {
    cout << fixed << setprecision(6);
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    // cin >> _;
    while (_--)solve();
}

 

C汉诺塔

待补;

D归零

 签到题;

#include<bits/stdc++.h>

#define ll long long
#define alls(x) x.begin(),x.end()
#define ull unsigned long long
#define lowbit(x) x&-x
#define lc p<<1
#define rc p<<1|1
#define PII pair<int,int>
#define vi vector<int>
using namespace std;
const int mod = 998244353;
const int N = 1e6 + 10;
int f(int x)
{
    int cnt = 0;
    while(x)
    {
        cnt+=x%10;
        x/=10;
    }
    return cnt;
}
int a[N];
void preWork()
{
    for(int i = 0;i<10;i++)a[i] = 1;
    for(int i = 10;i<=1000000;i++)
        a[i] = a[i-f(i)]+1;
}
void solve() {
    int n;
    cin >> n;
    cout<<a[n]<<'\n';
}

int main() {
    cout << fixed << setprecision(6);
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    preWork();
     cin >> _;
    while (_--)solve();
}
E激活锚点

 kruskal板子

对所有锚点求最小生成树,然后再找到起点到任一锚点的最近距离加上就可以。

(不能对所有节点一起求最小生成树,因为起点点不是锚点,起点只能连接一个边)

#include<bits/stdc++.h>
#define ll long long
#define alls(x) x.begin(),x.end()
#define ull unsigned long long
#define lowbit(x) x&-x
#define lc p<<1
#define rc p<<1|1
#define PII pair<int,int>
#define vi vector<int>
using namespace std;
const int mod = 998244353;
const int N = 1e6+10;
struct edge{
    int from,to;
    double val;
    bool operator<(const edge& b)const{
        return val<b.val;
    }
};
int p[N];
int find(int x)
{
    if(x!=p[x])p[x] = find(p[x]);
    return p[x];
}
void solve()
{
    vector<pair<double,double>>a;
    int x,y,n;
    cin >> x >> y >> n;
    double res = 1e9;
    for(int i = 1;i<=n;i++)p[i] =i;
    a.resize(n+1);
    for(int i = 1;i<=n;i++)
    {
        cin >> a[i].first >> a[i].second;
        res = min(res,sqrt(1.0 * (x-a[i].first) * (x-a[i].first) + 1.0*(y-a[i].second) * (y-a[i].second)));
    }
    vector<edge>b;
    for(int i = 1;i<=n;i++)
    {
        for(int j = i+1;j<=n;j++)
        {
            b.push_back({i,j,sqrt((a[i].first-a[j].first) * (a[i].first - a[j].first) + (a[i].second - a[j].second) * (a[i].second - a[j].second))});
        }
    }
//    for(auto i:b)
//    {
//        cout<<i.from<<" "<<i.to <<" "<<i.val<<endl;
//    }
    sort(alls(b));
    int m = b.size();
    int cnt = 0;
    for(int i = 0; i < m; i++)
    {
        int pa = find(b[i].from);
        int pb = find(b[i].to);
        if(pa != pb){
            //cout<<b[i].from<<" "<<b[i].to<<endl;
            res += b[i].val;
            p[pa] = pb;
            ++cnt;
        }
        if(cnt==n-1)break;
    }
    cout<<res<<'\n';
}
int main()
{
    cout<<fixed<<setprecision(10);
    ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    int _ = 1;
    cin >> _;
    while(_--)solve();
}
F买蛋糕

签到题;

#include<bits/stdc++.h>

#define ll long long
#define alls(x) x.begin(),x.end()
#define ull unsigned long long
#define lowbit(x) x&-x
#define lc p<<1
#define rc p<<1|1
#define PII pair<int,int>
#define vi vector<int>
using namespace std;
const int mod = 998244353;
const int N = 1e6 + 10;
void solve() {
    int n;
    cin >> n;
    int a,b,c;
    int ans = 0;
    for(int i = 0;i<n;i++)
    {
        cin >> a >> b >> c ;
        ans+=(a+b+c)>=100;
    }
    cout<<ans<<'\n';
}

int main() {
    cout << fixed << setprecision(6);
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
//     cin >> _;
    while (_--)solve();
}
G区间翻转

 签到题;

#include<bits/stdc++.h>

#define ll long long
#define alls(x) x.begin(),x.end()
#define ull unsigned long long
#define lowbit(x) x&-x
#define lc p<<1
#define rc p<<1|1
#define PII pair<int,int>
#define vi vector<int>
using namespace std;
const int mod = 998244353;
const int N = 1e6 + 10;
void solve() {
    int n,m,k,L,R;
    cin >> n >> m >> k;
    while(k--)
    {
        cin >>L >> R;
        if(m<=R && m>=L)
        {
            m = R-m+L;
//            cout<<m<<endl;
        }
    }
    cout<<m<<'\n';
}

int main() {
    cout << fixed << setprecision(6);
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
//     cin >> _;
    while (_--)solve();
}
H点燃星海

就是求连通块数量,dfs跑一遍就好;

 

#include<bits/stdc++.h>

#define ll long long
#define alls(x) x.begin(),x.end()
#define ull unsigned long long
#define lowbit(x) x&-x
#define lc p<<1
#define rc p<<1|1
#define PII pair<int,int>
#define vi vector<int>
using namespace std;
const int mod = 998244353;
const int N = 1e3 + 10;
int n,m;
char g[N][N];
bool vis[N][N];
void dfs(int i,int j)
{
    if(vis[i][j])return;
    vis[i][j] = true;
    if(g[i][j]=='0')return;
    dfs(i,(j+1)%m);
    dfs(i,(j-1+m)%m);
    dfs((i+1)%n,j);
    dfs((i-1+n)%n,j);
}
void solve() {
    cin >> n>> m;
    int ans = 0;
    for(int i = 0;i<n;i++)cin >> g[i];
    for(int i = 0;i<n;i++)
    {
        for(int j = 0;j<m;j++)
        {
            if(g[i][j]=='1' && !vis[i][j]) {
                ++ans;
                dfs(i,j);
            }
        }
    }
    cout<<ans<<'\n';
}

int main() {
    cout << fixed << setprecision(6);
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
//     cin >> _;
    while (_--)solve();
}
I洗牌

 不要被吓到,看数据范围模拟即可;

#include<bits/stdc++.h>

#define ll long long
#define alls(x) x.begin(),x.end()
#define ull unsigned long long
#define lowbit(x) x&-x
#define lc p<<1
#define rc p<<1|1
#define PII pair<int,int>
#define vi vector<int>
using namespace std;
const int mod = 998244353;
const int N = 1e6 + 10;
void solve() {
    int n,l,r;
    cin >> n;
    string s;
    for(char i = '1';i<='1'+54;i++)
    {
        s+=i;
    }
    while(n--)
    {
        cin >>l >> r;
        l--,r--;
        string y = s.substr(l,r-l+1);
        s.erase(l,r-l+1);
        s = y + s;
    }
    for(int i = 0;i<54;i++)cout<<int(s[i]-'0')<<" ";
}

int main() {
    cout << fixed << setprecision(6);
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
//     cin >> _;
    while (_--)solve();
}
J初等元素论

待补;

K翻转排序

 易知交换a[i],a[j]可以通过翻转区间[i,j],[i+1,j-1]实现(j-i>=2时);

#include<bits/stdc++.h>

#define ll long long
#define alls(x) x.begin(),x.end()
#define ull unsigned long long
#define lowbit(x) x&-x
#define lc p<<1
#define rc p<<1|1
#define PII pair<int,int>
#define vi vector<int>
using namespace std;
const int mod = 998244353;
const int N = 1e6 + 10;
void solve() {
    int n,m,k,L,R;
    cin >> n >> m >> k;
    while(k--)
    {
        cin >>L >> R;
        if(m<=R && m>=L)
        {
            m = R-m+L;
//            cout<<m<<endl;
        }
    }
    cout<<m<<'\n';
}

int main() {
    cout << fixed << setprecision(6);
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
//     cin >> _;
    while (_--)solve();
}
L分煎饼

 计算几何 + 二分,待补;

M画图

模拟

#include<bits/stdc++.h>

#define ll long long
#define alls(x) x.begin(),x.end()
#define ull unsigned long long
#define lowbit(x) x&-x
#define lc p<<1
#define rc p<<1|1
#define PII pair<int,int>
#define vi vector<int>
using namespace std;
const int mod = 998244353;
const int N = 1e3 + 10;
int n, m;
int a[N][N];

void line(int x1, int x2, int y1, int y2) {
    if (x1 == x2) {
        if (y1 > y2)swap(y1, y2);
        for (int i = y1; i <= y2; i++)a[x1][i] = 1;
        return;
    }
    if (y1 == y2) {
        if (x1 > x2)swap(x1, x2);
        for (int i = x1; i <= x2; i++)a[i][y1] = 1;
        return;
    }
    if (x1 > x2) {
        swap(x1, x2);
        swap(y1, y2);
    }
    if (y1 < y2) {
        for (int i = x1, j = y1; i <= x2; i++, j++)
            a[i][j] = 1;
    } else {
//        cout << "HERE" << endl;
        for (int i = x1, j = y1; i <= x2; i++, j--)a[i][j] = 1;
    }
}

void solve() {
    cin >> n >> m;
    int k;
    cin >> k;
    int op, x1, x2, y1, y2;
    while (k--) {
        cin >> op >> x1 >> y1 >> x2 >> y2;
        if (op == 1) {
            line(x1, x2, y1, y2);
        } else {
            line(x1, x1, y1, y2);
            line(x2, x2, y1, y2);
            line(x1, x2, y1, y1);
            line(x1, x2, y2, y2);
        }
    }
    //cout<<"HELLO"<<endl;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (a[i][j])cout << "x";
            else cout << '.';
        }
        cout << '\n';
    }
}

int main() {
    cout << fixed << setprecision(6);
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
//     cin >> _;
    while (_--)solve();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值