首页 > 其他分享 >YACS 2023年9月月赛 甲组 题解

YACS 2023年9月月赛 甲组 题解

时间:2023-10-16 22:13:55浏览次数:35  
标签:YACS pp ch 题解 ll 甲组 include top define

题目链接1

题目链接2

题目链接3

榜单终于公布了,这应该是第二长的榜单公布吧。(最长的一次是去年八月,拖到九月开始后才公布)

 

T1 是傻逼数据结构不说了吧,对于每个点枚举以他为角的 $k\times k$ 的四个正方形算一下点的数量,用 $cdq$ 或者扫描线都行。

看这个题目编号是 $81$,看来是很久以前就出的题这个月没题了凑出来的。

 

T2 是我认为比较好的一道题,虽然一眼看出诈骗。

先分析题目类型,显然是 DP,$m$ 一定要计入时间复杂度的,$n$ 应该也有,复杂度就是 $O(n\times m)$。

这点时间够什么?可以够预处理 $f_{i,j}$,就是后 $i$ 位随便填能不能模 $m$ 余 $j$。

这点东西能有什么用?我们发现,两个数的位数相等,如果一个数的第一位大于另一个数的第一位,那么这个数后面就算全是 $0$ 也比另外一个数字大,有了这个结论,这一题就很简单了。

从高到低逐位确定,先从 $9$ 开始是,如果后面可以拼出适当的模数使得其是 $m$ 的倍数,那就选它,继续往第一位的地方试就可以了。

#include <bits/stdc++.h>
#define For(i, a, b) for (int i = (a); i <= (b); i ++)
#define foR(i, a, b) for (int i = (a); i >= (b); i --)
using namespace std;
int m;
int f[2005][2005], pre[2005];
char s[2005];
int main () {
    scanf ("%s%d", s + 1, &m);
    int len = strlen (s + 1);
    pre[0] = 1;
    For (i, 1, 2000) pre[i] = pre[i - 1] * 10 % m;
    f[len + 1][0] = 1;
    foR (i, len + 1, 2) {
        if (s[i - 1] == '?') {
            For (k, 0, 9)
                For (j, 0, m - 1) f[i - 1][(j + pre[len + 1 - i] * k % m) % m] |= f[i][j];
        } else {
            For (j, 0, m - 1)
                f[i - 1][(j + pre[len + 1 - i] * (s[i - 1] - '0') ) % m] |= f[i][j];
        }
    }
    if (!f[1][0]) {
        cout << "Impossible";
        return 0;
    }
    int cur = 0;
    For (i, 1, len) {
        if (s[i] == '?') {
            foR (j, 9, 0) {
                if (f[i + 1][(cur - pre[len - i] * j % m + m) % m]) {
                    cout << j;
                    cur = (cur - pre[len - i] * j % m + m) % m;
                    break;
                }
            }
        } else {
            cout << s[i];
            cur = (cur - pre[len - i] * (s[i] - '0') % m + m) % m;
        }
    }
    return 0;
}

 

 

T3 居然是原!二话没说直接贺!讲下大概思路吧。如果有任意两幅画是包含关系,那么只取大的就行了,这样以后按长升序排序必然有宽单调下降。

设 $f_i$ 为打包 $1\cdots i$ 的最小花费,$f_i=\min{f_{j-1} + b_j * a_i}$,显然是个斜率优化,然而直接贺数组开小也就挂了 $20pts$?

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#include <unordered_map>
#define ll long long
#define reg register
#define fo(a,b,c) for(reg ll a=b;a<=c;a++)
#define re(a,b,c) for(reg ll a=b;a>=c;a--)
#define pii pair<ll,ll>
#define fi first
#define pb push_back
#define se second
#define mod 1000000007
#define inf mod
using namespace std;
inline ll gi()
{
    ll x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = (x<<1) + (x<<3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}
ll _=1;
const int N=300005;
ll ans[N],f[N];
struct IO
{
    ll x,y;
}p[N],pp[N];
pii q[N];
bool co(IO a,IO b)
{
    if(a.x!=b.x) return a.x<b.x;
    else return a.y>b.y;
}
ll X(ll a,ll b)
{
    return a-b;
}
ll Y(ll a,ll b)
{
    return a-b;
}
ll stk[N];
void sol()
{
    ll n=gi(),h=1,t=1;
    fo(i,1,n)
    {
        pp[i].x=gi(),pp[i].y=gi();
    }
    ll top=0;
    sort(pp+1,pp+1+n,co);
    fo(i,1,n)
    {
        while(top&&pp[i].y>pp[stk[top]].y)
        {
            top--;
        }
        top++;
        stk[top]=i;
    }
    fo(i,1,top)
    {
        p[i]=pp[stk[i]];
    }
    n=top;
/*    cout<<'\n';
    fo(i,1,n)
    {
        cout<<p[i].x<<" "<<p[i].y<<'\n';
    }*/
    q[1].fi=-p[1].y;
    
    ll la=0;
    fo(i,1,n)
    {
        while(h<t&&X(q[h+1].fi,q[h].fi)*p[i].x>=Y(q[h+1].se,q[h].se))
        {
            h++;
        }
/*        fo(j,h,t)
        {
            cout<<"TEST "<<i<<" "<<j<<" "<<q[j].fi<<" "<<q[j].se<<'\n';
        }*/
//        cout<<q[h].fi<<" "<<q[h].se<<'\n';
        f[i]=q[h].se-q[h].fi*p[i].x;
        ll x=-p[i+1].y,y=f[i];
        while(h<t&&Y(y,q[t].se)*X(q[t].fi,q[t-1].fi)<=Y(q[t].se,q[t-1].se)*X(x,q[t].fi))
        {
            t--;
        }
        
        t++;
        q[t].fi=x;
        q[t].se=y;
        
    }
/*    fo(i,1,n)
    {
        cout<<f[i]<<" ";
    }*/
    cout<<f[n];
}
int main()
{
//    _=gi();
    while(_--)
    {
        sol();
//        printf("\n");
    }
    return 0;
}

 

标签:YACS,pp,ch,题解,ll,甲组,include,top,define
From: https://www.cnblogs.com/Xy-top/p/17768492.html

相关文章

  • 题解整理
    CF1740ACF1740BCF1740DCF1711BCF1253BCF1080BCF1237ACF1743ACF1743CCF1743BCF1370B......
  • P9744 消除序列 题解
    本题有多种解法,我这里先讲一个我的考场做法吧。切入点我们发现我们至多使用一次操作一,而剩下部分的\(0\)肯定是依靠操作二补全,操作三的作用只是用来填补操作一的空白的,所以我们发现我们对一个序列的操作一定是前一段用操作一和操作三,后一段用操作二。思路1一开始考虑暴力\(......
  • CEIT 23练习编程题 题解
    本文部分题目提供c/c++两种解法,顺便可以让你们知道c++在面对某些题时的优势部分题目提供多种解法日期格式化C#include<stdio.h>intmain(){intm,d,y;scanf("%d-%d-%d",&m,&d,&y);printf("%04d-%02d-%02d",y,m,d);return0;}02d的含义:当有效数......
  • 【题解】「KDOI-06-S」补题
    「KDOI-06-S」A.「KDOI-06-S」消除序列赛时写了一个\(O(nq)\)的线性DP,喜提60分。注意到如果操作1被使用,则一定只会使用一次,而且在最优策略中一定是第一次使用操作1。则我们可以通过以下方式进行操作,使序列满足条件:首先执行\(a_i\)和\(\sum^{j\lei,i\inP}_{j=......
  • [COCI2015-2016#4] ENDOR 题解
    [COCI2015-2016#4]ENDOR题解首先要发现一个很重要的性质,那就是两只变色龙碰撞后回头,等效于两只变色龙继续往前走,其中向右走的颜色不变,而向左走的要改变颜色。那这样就有一种\(O(n^2)\)的做法:对于向右的变色龙,直接贡献答案;对于向左的变色龙,我们按照碰到的先后顺序枚举它前面......
  • 【题解】AtCoder-ARC167
    AtCoder-ARC167AToastsforBreakfastParty一定不会有空盘,问题转化成\(2m\)个数,其中\(2m-n\)个是\(0\),这样一定是最大值和最小值一起,次大值和次小值一起,以此类推。提交记录:Submission-AtCoderAtCoder-ARC167BProductofDivisors\(A^B=\prod_ip_i^{Bc_i}\),那么答案......
  • CF1119F Niyaz and Small Degrees 题解
    原题翻译首先\(O(n^2\logn)\)的dp是simple的,我们设\(dp_{i,0/1}\)表示以\(i\)为根,\(i\)到\(fa_i\)这条边删/不删的最小权值和。转移是一个非常trick的问题,只需要假设所有都选\(dp_{i,0}\),然后把所有儿子按照\(dp_{v,1}+w(u,v)-dp_{v,0}\)排序,选前\(d......
  • P9745 「KDOI-06-S」树上异或 题解
    P9745「KDOI-06-S」树上异或题解\(x_i=0\)这题一看就不是很可做,先考虑部分分。对于一条链的情况,我们可以枚举上一个断边的位置,然后转移。一看数据范围,估计和值域有关,所以考虑\(x_i=1\)的部分分,如果全部点权都是1,那么一种方案只有0和1两种取值,考虑这个状态设计:\(f......
  • [ARC167D] Good Permutation 题解
    题意对于一个长度为\(N\)的排列\(Q\),定义其为好的,当且仅当对于任意整数\(i\in\left[1,N\right]\),在进行若干次操作\(i\leftarrowQ_i\)后可以得到\(i=1\)。给定一个排列\(P\),定义一次操作为交换两个数。定义\(M\)为可以将\(P\)变为一个好的的排列的最小操......
  • 计算机网络的分组转发算法例题解析
    例题展示例题解决将题目中要求的ip地址与相对应的子网掩码进行二进制上面的相与即可,若是与目的ip地址一致,那么就直接跳转到其对应的那个接口;否则就直接跳转到默认接口;本题答案为R2;......