「CSP-S模拟赛」2019第二场

目录

  • T1 Jam的计数法

    • 题目
    • 考场思路(正解)
  • T2 「TJOI / HEOI2016」排序
    • 题目
    • 考场思路(假正解)
    • 正解
  • T3 「THUWC 2017」随机二分图
    • 题目
    • 考场思路
    • 正解


这场考试的数据感觉很水。
\(T1\) 签到不解释,\(T2\) 期望 \(50pts\) 结果有 \(100pts\),\(T3\) 一如既往地不可做...
___

T1 Jam的计数法

题目

点这里

考场思路(正解)

其实没有什么好说的,找找规律即可,看看代码吧。

#include<cstdio>
// #define FILEOI
#define rep(i,__l,__r) for(int i=__l,i##_end_=__r;i<=i##_end_;++i)
#define dep(i,__l,__r) for(int i=__l,i##_end_=__r;i>=i##_end_;--i)
#define cg (c=getchar())
template<class T>inline void qread(T& x){
    x=0;char c;bool f=0;
    while(cg<'0'||'9'<c)if(c=='-')f=1;
    for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    if(f)x=-x;
}
template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
inline int qread(){
    int x=0;char c;bool f=0;
    while(cg<'0'||'9'<c)if(c=='-')f=1;
    for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    return f?x:-x;
}
#undef cg
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}
template<class T>void fwrit(T x){
    if(x<0)return (void)(putchar('-'),fwrit(-x));
    if(x>10)fwrit(x/10);
    return (void)(putchar(x%10^48));
}

const int MAXW=25;
int s,t,w,num[(MAXW<<2)+5],T=5;
char sn[(MAXW<<2)+5];

inline void init(){
    qread(s,t,w);
    scanf("%s",sn+1);
    rep(i,1,w)num[i]=sn[i]-'a'+1;
}

inline void putNum(){
    for(int i=1;i<=w;++i)printf("%c",num[i]+'a'-1);
    putchar('\n');
}

inline void addOne(){
    bool f=true;
    for(int i=w;i>=1;--i)if(num[i]<t-w+i){
        ++num[i],f=false;
        for(int j=i+1;j<=w;++j)num[j]=num[j-1]+1;
        break;
    }
    if(f)return;
    putNum();
}

signed main(){
#ifdef FILEOI
    freopen("number.in","r",stdin);
    freopen("number.out","w",stdout);
#endif
    init();
    while(T--)addOne();
    return 0;
}

T2 「TJOI / HEOI2016」排序

题目

点这里

考场思路(假正解)

直接看的 \(50\%\) 的数据范围,发现可以使用区间桶排序,时间复杂度 \(O(nm)\)。

#include<cstdio>
// #define FILEOI
#define rep(i,__l,__r) for(int i=__l,i##_end_=__r;i<=i##_end_;++i)
#define dep(i,__l,__r) for(int i=__l,i##_end_=__r;i>=i##_end_;--i)
#define cg (c=getchar())
template<class T>inline void qread(T& x){
    x=0;char c;bool f=0;
    while(cg<'0'||'9'<c)if(c=='-')f=1;
    for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    if(f)x=-x;
}
template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
inline int qread(){
    int x=0;char c;bool f=1;
    while(cg<'0'||'9'<c)if(c=='-')f=0;
    for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    return f?x:-x;
}
#undef cg
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}
template<class T>void fwrit(T x){
    if(x<0)return (void)(putchar('-'),fwrit(-x));
    if(x>10)fwrit(x/10);
    return (void)(putchar(x%10^48));
}

const int MAXN=1e5;

int n,m,q,a[MAXN+5],t[MAXN+5];

inline void init(){
    qread(n,m);
    rep(i,1,n)qread(a[i]);
}

inline void getOperation(){
    int op,l,r,li,ri;
    while(m--){
        li=n,ri=0;
        qread(op,l,r);
        rep(i,l,r)++t[a[i]],li=Min(li,a[i]),ri=Max(ri,a[i]);
        if(op==0){
            rep(i,l,r){
                while(t[li]==0)++li;
                a[i]=li,t[li]=0;
            }
        }
        else if(op==1){
            rep(i,l,r){
                while(t[ri]==0)--ri;
                a[i]=ri,t[ri]=0;
            }
        }
    }
    printf("%d\n",a[qread()]);
}

signed main(){
#ifdef FILEOI
    freopen("sort.in","r",stdin);
    freopen("sort.out","w",stdout);
#endif
    init();
    getOperation();
    return 0;
}

期望得分只有 \(50pts\),但是数据测出来,居然可以 \(A\) 掉...所以叫伪正解...

正解

我们发现,对于一个 \(x\),将小于 \(x\) 的数换成 \(0\),大于等于 \(x\) 的数换成 \(1\) 之后,所得到的排序结果其实是一样的。
但是这样做有唯一的缺陷,就是我们只知道最后 \(q\) 位置的数是 \(0\) 还是 \(1\)。
其实很好解决,二分这个 \(x\) 即可。
这里先把标称附上
std version

#include <cstdio>
#include <cstring>
#include <cctype>
#define lc o << 1
#define rc o << 1 | 1
#define mid (l + r) / 2
using namespace std;

const int N = 100010;
int n, m, p;
int T[4 * N], lazy[4 * N];    // segment tree
int a[N], ch[N], L[N], R[N];  // the information by reading

inline int read() {
    char ch = getchar();
    int x = 0;
    while (!isdigit(ch)) ch = getchar();
    while (isdigit(ch)) {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x;
}

inline void build(int o, int l, int r, int x) {
    if (l == r) {
        T[o] = a[l] >= x;
        lazy[o] = 0;
        return;
    }
    build(lc, l, mid, x);
    build(rc, mid + 1, r, x);
    T[o] = T[lc] + T[rc];
    lazy[o] = 0;
}

inline void pushdown(int o, int l, int r) {
    if (!lazy[o])
        return;
    lazy[lc] = lazy[rc] = lazy[o];
    if (lazy[o] == 1) {
        T[lc] = mid - l + 1;
        T[rc] = r - mid;
    } else
        T[lc] = T[rc] = 0;
    lazy[o] = 0;
}

inline int query(int o, int l, int r, int x, int y) {
    if (x <= l && y >= r)
        return T[o];
    if (x > r || y < l)
        return 0;
    pushdown(o, l, r);
    return query(lc, l, mid, x, y) + query(rc, mid + 1, r, x, y);
}

inline int queryPoint(int o, int l, int r, int x) {
    if (l == x && r == x)
        return T[o];
    pushdown(o, l, r);
    if (x <= mid)
        return queryPoint(lc, l, mid, x);
    else
        return queryPoint(rc, mid + 1, r, x);
}

inline void update(int o, int l, int r, int x, int y, int val) {
    if (x <= l && y >= r) {
        T[o] = val * (r - l + 1);
        lazy[o] = val ? 1 : -1;
        return;
    }
    if (x > r || y < l)
        return;
    pushdown(o, l, r);
    update(lc, l, mid, x, y, val);
    update(rc, mid + 1, r, x, y, val);
    T[o] = T[lc] + T[rc];
}

inline bool check(int x) {
    build(1, 1, n, x);
    for (int i = 1; i <= m; i++) {
        int cnt1 = query(1, 1, n, L[i], R[i]);
        if (ch[i] == 0) {
            update(1, 1, n, R[i] - cnt1 + 1, R[i], 1);
            update(1, 1, n, L[i], R[i] - cnt1, 0);
        } else {
            update(1, 1, n, L[i], L[i] + cnt1 - 1, 1);
            update(1, 1, n, L[i] + cnt1, R[i], 0);
        }
    }
    return queryPoint(1, 1, n, p);
}

int main() {
    freopen("sort.in","r",stdin);
    freopen("sort.out","w",stdout);
    n = read();
    m = read();
    for (int i = 1; i <= n; i++) a[i] = read();
    for (int i = 1; i <= m; i++) {
        ch[i] = read();
        L[i] = read();
        R[i] = read();
    }
    p = read();
    int ll = 1, rr = n, midd, ans;
    while (ll <= rr) {
        midd = (ll + rr) >> 1;
        if (check(midd))
            ans = midd, ll = midd + 1;
        else
            rr = midd - 1;
    }
    printf("%d\n", rr);
    return 0;
}

My version

#include<cstdio>
// #define FILEOI
#define lc (i<<1)
#define rc (i<<1|1)
#define rep(i,__l,__r) for(int i=__l,i##_end_=__r;i<=i##_end_;++i)
#define dep(i,__l,__r) for(int i=__l,i##_end_=__r;i>=i##_end_;--i)
#define cg (c=getchar())
template<class T>inline void qread(T& x){
    x=0;char c;bool f=0;
    while(cg<'0'||'9'<c)if(c=='-')f=1;
    for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    if(f)x=-x;
}
template<class T,class... Args>inline void qread(T& x,Args&... args){qread(x),qread(args...);}
inline int qread(){
    int x=0;char c;bool f=1;
    while(cg<'0'||'9'<c)if(c=='-')f=0;
    for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
    return f?x:-x;
}
#undef cg
template<class T>inline T Max(const T x,const T y){return x>y?x:y;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}
template<class T>void fwrit(T x){
    if(x<0)return (void)(putchar('-'),fwrit(-x));
    if(x>10)fwrit(x/10);
    return (void)(putchar(x%10^48));
}

const int MAXN=1e5;
const int MAXM=1e5;

struct change{int op,l,r;}p[MAXM+5];
struct node{
    int l,r,mid,t1,lazy;
    node(){lazy=-1;}
    node(const int L,const int R,const int M):l(L),r(R),mid(M){lazy=-1;}
}tre[(MAXN<<2)+5];
int n,m,a[MAXN+5],t[MAXN+5],q;

inline void init(){
    qread(n,m);
    rep(i,1,n)qread(a[i]);
    for(int i=1;i<=m;++i)p[i]=change{qread(),qread(),qread()};
    qread(q);
}

inline void pushup(const int i){tre[i].t1=tre[lc].t1+tre[rc].t1;}

inline void pushdown(const int i){
    if(tre[i].l^tre[i].r){
        if(tre[i].lazy==1){
            tre[lc].lazy=tre[rc].lazy=1;
            tre[lc].t1=(tre[lc].r-tre[lc].l+1);
            tre[rc].t1=(tre[rc].r-tre[rc].l+1);
        }
        else if(tre[i].lazy==0){
            tre[lc].lazy=tre[rc].lazy=0;
            tre[lc].t1=tre[rc].t1=0;
        }
    }
    tre[i].lazy=-1;
}

inline void buildtre(const int i,const int l,const int r,const int x){
    // printf("buildtre : %d %d %d %d\n",i,l,r,x);
    int mid=(l+r)>>1;
    tre[i]=node(l,r,mid);
    if(l==r)return (void)(tre[i].t1=(a[l]>=x));
    buildtre(lc,l,mid,x);
    buildtre(rc,mid+1,r,x);
    pushup(i);
}

inline int query(const int i,const int l,const int r){
    // printf("query : %d %d %d\n",i,l,r);
    if(l<=tre[i].l&&tre[i].r<=r)return tre[i].t1;
    if(tre[i].lazy!=-1)pushdown(i);
    int ret=0;
    if(l<=tre[i].mid)ret+=query(lc,l,r);
    if(tre[i].mid<r)ret+=query(rc,l,r);
    pushup(i);
    return ret;
}

inline void update(const int i,const int l,const int r,const int var){
    // if(l>r)return;
    // printf("update : %d to %d, %d\n",l,r,var);
    if(l<=tre[i].l&&tre[i].r<=r){
        tre[i].lazy=var;
        tre[i].t1=(tre[i].r-tre[i].l+1)*var;
        return;
    }
    if(tre[i].lazy!=-1)pushdown(i);
    if(l<=tre[i].mid)update(lc,l,r,var);
    if(tre[i].mid<r)update(rc,l,r,var);
    pushup(i);
}

inline int query(const int i,const int p){
    // printf("update : %d %d\n",i,p);
    if(tre[i].l==tre[i].r)return tre[i].t1;
    if(tre[i].lazy!=-1)pushdown(i);
    int ret;
    if(p<=tre[i].mid)ret=query(lc,p);
    else ret=query(rc,p);
    pushup(i);
    return ret;
}

inline bool check(const int x){
    // printf("Now check : x == %d\n",x);
    buildtre(1,1,n,x);
    // for(int i=1;i<=13;++i)printf("tre[%d] : %d %d %d %d %d\n",i,tre[i].l,tre[i].r,tre[i].mid,tre[i].t1,tre[i].lazy);
    rep(i,1,m){
        int cnt1=query(1,p[i].l,p[i].r);
        int cnt0=p[i].r-p[i].l+1-cnt1;
        // printf("query : %d %d, cnt1 == %d, cnt0 == %d\n",p[i].l,p[i].r,cnt1,cnt0);
        if(p[i].op==0){
            if(cnt0)update(1,p[i].l,p[i].l+cnt0-1,0);
            if(cnt1)update(1,p[i].l+cnt0,p[i].r,1);
            // printf("update : %d to %d, %d\n",p[i].l,p[i].l+cnt0-1,0);
            // printf("update : %d to %d, %d\n",p[i].l+cnt0,p[i].r,1);
        }
        else{
            if(cnt1)update(1,p[i].l,p[i].l+cnt1-1,1);
            if(cnt0)update(1,p[i].l+cnt1,p[i].r,0);
            // printf("update : %d to %d, %d\n",p[i].l,p[i].l+cnt1-1,0);
            // printf("update : %d to %d, %d\n",p[i].l+cnt1,p[i].r,1);
        }
        // printf("Now The info of the tre :\n");
        // for(int j=1;j<=13;++j)printf("tre[%d] : %d %d %d %d %d\n",j,tre[j].l,tre[j].r,tre[j].mid,tre[j].t1,tre[j].lazy);
    }
    // printf("When x == %d,ans == %d\n",x,query(1,q));
    return query(1,q);
}

inline void biSearch(){
    int l=0,r=n,x=0,ans;
    while(l<=r){
        x=(l+r)>>1;
        if(check(x))ans=x,l=x+1;
        else r=x-1;
    }
    fwrit(ans),putchar('\n');
}

signed main(){
#ifdef FILEOI
    freopen("sort.in","r",stdin);
    freopen("sort.out","w",stdout);
#endif
    init();
    biSearch();
    return 0;
}

T3 「THUWC 2017」随机二分图

题目

点这里

考场思路

看到二分图,再看到数学期望,直接跳过 虽然后面已经没有题可以跳了

正解

讲了半天,有点昏,先让我缓一下...

原文地址:https://www.cnblogs.com/Arextre/p/12210548.html

时间: 2024-10-09 04:22:01

「CSP-S模拟赛」2019第二场的相关文章

「CSP-S模拟赛」2019第一场

目录 T1 小奇取石子 题目 考场思路 正解 T2 「CCO 2017」专业网络 题目 考场思路 题解 T3 「ZJOI2017」线段树 题目 考场思路 正解 这场考试感觉很奇怪. \(T1.T2\) 都缺一个小特判. \(T3\) 打了个比暴力优的暴力 还是暴力,但是不知道为什么 \(WA\) 穿了. 考试的时候还玩扫雷... 其实,菜是原罪啊... ___ T1 小奇取石子 题目 点这里 考场思路 刚开始差点被自己坑了,开考 \(5min\) 就码出了一个可以惨痛爆零的 \(01\) 背包.

「2019-8-11提高模拟赛」女装盛宴 (flag)

传送门 Solution? 基环树+倍增+双指针 第一次因为#define int long long而玄学RE 为什么标程都不用开\(long long\)啊 Code? /*玄学RE 看来又是define ll long long 也有bug*/ #include<bits/stdc++.h> #define ll long long #define double #define dbg1(x) cerr<<#x<<"="<<(x)&

「csp校内训练 2019-10-24」解题报告

「csp校内训练 2019-10-24」解题报告 T1.猴猴吃苹果 \(Description\) 猴猴最喜欢在树上玩耍,一天猴猴又跳上了一棵树,这棵树有 \(N \ (N \leq 50000)\) 个苹果,每个苹果有一个编号,分别为 \(0\) ~ \(N - 1\) 它们之间由 \(N-1\) 个树枝相连,猴猴可以从树枝的一端爬到树枝的另一端,所以猴猴可以从任意一个苹果的位置出发爬到任意猴猴想去的苹果的位置. 猴猴开始在编号为 \(K \ (K < N)\) 的苹果的位置,并且把这个苹果吃

「csp校内训练 2019-10-30」解题报告

「csp校内训练 2019-10-30」解题报告 T1.树 题目链接(逃) \(Description\): 现在有一棵树,共 \(N\) 个节点. 规定:根节点为 \(1\) 号节点,且每个节点有一个点权. 现在,有 \(M\) 个操作需要在树上完成,每次操作为下列三种之一: \(1 \ x \ a\):操作 \(1\),将节点 \(x\) 点权增加 \(a\). \(2 \ x \ a\):操作 \(2\),将以节点 \(x\) 为根的子树中所有点的权值增加 \(a\). \(3 \ x\)

小王子「CSP多校联考 2019」

题意 又是一位被\(oi\)耽误了的文学家,甚至有一种做\(lxl\)题的感觉. 给定一棵树,向上加若干新边.现在可以删除一条树边一条新边,求将这棵树截断的方案数. 思路 对于一条边,如果没有新边覆盖他,显然删除这条边再删除任意一条新边均可. 如果有一条新边覆盖,那么删除这条树边再删除这条新边,只有一种方法. 否则不可能. 先把边转换为点然后跑一个树上差分即可. 原文地址:https://www.cnblogs.com/ilverene/p/11812885.html

liu_runda 给辣鸡蒟蒻做的 NOIP模拟赛 1.0 第二题 任(duty) 题解

问题 B: 任(duty) 时间限制: 2 Sec  内存限制: 512 MB 题目描述 liu_runda退役之后就失去梦想开始咸鱼生活了- Bilibili夏日画板活动中,所有人都可以在一块画板上进行像素画创作.UOJ群有一群无聊的人决定在画板上创作一个50*50的UOJ的LOGO.如下图. 这块画板实际上是很大的矩形网格.一个网格是一像素. 一个人每三分钟才能画一个像素.所以liu_runda的咸鱼生活非常无聊. 郭神表示他实在是看不下去liu_rudna这只颓狗了,于是随手出了一道神题,

上海锦隆驾校「科目三」2019年考试心得实录

最近满分通过了科目三道路驾驶技能和理论考试,确实发现有很多技巧和坑点,按照我个人的习惯,还是希望能把他作为经验放在网上,供大家参考和学习.至少能让即将参加考试的上海学院能有个好心态并通过考试. 谢谢教练的这不到三个月的耐心指导 写在前面,选个好教练非常重要,我的教练姓:吕,是位女教练.之前是开长途火车的,教我们的时候,基本都是很实用的驾驶技能,刚开始不太相信,但考试和模拟期间看到别人驾驶的技巧和转弯,真的没法看拿完驾照的第二天,我就直接租车上路了,一点问题都没有,非常轻松,连同事都说你不像刚拿驾

2019模拟赛09场解题报告

目录 2019模拟赛09场解题报告 目录la~~ 题一:瞬间移动 题二:食物订购 题三:马蹄印 题四:景观美化 2019模拟赛09场解题报告 标签(空格分隔): 解题报告 Forever_chen 2019.8.20 目录la~~ 题一:瞬间移动 [题面] 有一天,暮光闪闪突然对如何将一个整数序列a1,a2,...,an排序为一个不下降序列起了兴趣.身为一只年轻独角兽的她,只能进行一种叫做"单元转换"(unit shift)的操作.换句话说,她可以将序列的最后一个元素移动到它的起始位置

2019浙大计算机考研机试模拟赛(2)——概念专题

题目链接   引用自晴神OJ A - 边覆盖 B - 极大独立集 C - 稳定婚姻问题 D - 笛卡尔树 没赶得上全程的比赛,就做了两道,后面两道以后有时间再补.两道都是概念题,比较基础~ 以下是题解 A - 边覆盖 Case Time Limit: 200 MS (Others) / 400 MS (Java)       Case Memory Limit: 256 MB (Others) / 512 MB (Java) Accepted: 199      Total Submission