2017.6.11 校内模拟赛

题面及数据及std(有本人的也有原来的) :2017.6.11 校内模拟赛

T1

   

    自己在纸上模拟一下后就会发现

    可以用栈来搞一搞事情

    受了上次zsq 讲的双栈排序的启发。。

    具体就是将原盘子大小copy一下排个序

    用两个指针维护两个数组(原数据 和 排序后的数据), 即分为1数据和2数组

    将小于1指针指向的数据的2数组中的数据全部压入栈中

    后进行消除, 将栈栈顶元素与当前1数组中的1指针指向的元素进行比较

    相同则消除

    后重复过程

    直至指针超过N

    后判断一下是否两个指针都超过了N。。。

  

    

#include <algorithm>
#include <cstring>
#include <cstdio>
#include <stack>

#define Max 100090

void read (int &now)
{
    now = 0;
    register char word = getchar ();
    while (word < ‘0‘ || word > ‘9‘)
        word = getchar ();
    while (word >= ‘0‘ && word <= ‘9‘)
    {
        now = now * 10 + word - ‘0‘;
        word = getchar ();
    }
}

int N, M;

int dish[Max];
int data[Max];

class Stack_Type
{

    private :

        int Stack[Max];

        int Top_Cur;

    public :

        inline void Clear ()
        {
            Top_Cur = 0;
        }

        inline void Pop ()
        {
            Top_Cur --;
        }

        bool Empty ()
        {
            return Top_Cur == 0;
        }

        inline int Top ()
        {
            return Stack[Top_Cur];
        }

        inline void Push (int x)
        {
            Stack[++ Top_Cur] = x;
        }
};

Stack_Type Stack;

int main (int argc, char *argv[])
{
    freopen ("disk.in", "r", stdin);
    freopen ("disk.out", "w", stdout);
    int T;
    for (; scanf ("%d", &N) != EOF; )
    {
        memset (dish, 0, sizeof dish);
        memset (data, 0, sizeof data);

        bool flag = false;
        Stack.Clear ();
        for (int i = 1; i <= N; i ++)
        {
            read (dish[i]);
            data[i] = dish[i];
        }
        std :: sort (data + 1, data + 1 + N);
        register int pos_1 = 1, pos_2 = 1;
        for (; (pos_1 <= N || pos_2 <= N) && (Stack.Empty () || dish[pos_1] >= Stack.Top ()); )
        {
            for (; pos_2 <= N && dish[pos_1] >= data[pos_2]; )
                Stack.Push (data[pos_2 ++]);
            for (; !Stack.Empty () && pos_1 <= N && Stack.Top() == dish[pos_1]; Stack.Pop (), pos_1 ++);
        }
        if (pos_1 > N && pos_2 > N)
            printf ("Y\n");
        else
            printf ("J\n");
    }
    return 0;
}

T2

    这个题估计随便乱搞搞就能A吧。。

    看机房里众dalao 以各种奇怪的姿势AC此题。。

     

    思路:枚举每个点,算出对角线边缘的两个分别进行二分, 分别找出两个符合条件的边界点, 乘一乘就好了。。

    写了四个二分我也是醉了。。。写完后才想起来有 lower_bound 这个东西。。。

  

#include <algorithm>
#include <cstdio>

#define Max 10010

void read (int &now)
{
    now = 0;
    register char word = getchar ();
    bool temp = false;
    while (word < ‘0‘ || word > ‘9‘)
    {
        if (word == ‘-‘)
            temp = true;
        word = getchar ();
    }
    while (word >= ‘0‘ && word <= ‘9‘)
    {
        now = now * 10 + word - ‘0‘;
        word = getchar ();
    }
    if (temp)
        now = -now;
}

struct Data_
{
    int x, y;

    Data_ (int __x, int __y) : x (__x), y (__y) {};
    Data_ () {};

    bool operator < (const Data_ &now) const
    {
        if (this->x == now.x)
            return this->y < now.y;
        return this->x < now.x;
    }
};

inline int abs (int x)
{
    return x < 0 ? -x : x;
}

long long Answer;
int N;

bool Judge (Data_ now_1, Data_ now_2)
{
    if (now_2.y <= now_1.y)
        return true;
    if (abs (now_1.x + now_1.y + now_2.x - now_2.y) % 2 == 1)
        return true;
    if (abs (now_2.x - now_1.x + now_1.y + now_2.y) % 2 == 1)
        return true;
    return false;
}

Data_ point[Max];

bool ErFen_Judge (int now, int x, int y)
{
    Data_ res (x, y);
    return point[now] < res;
}

bool ErFen_Re_Judge (int now, int x, int y)
{
    if (point[now].x == x)
        return point[now].y > y;
    return point[now].x > x;
}

int main (int argc, char *argv[])
{
    freopen ("car.in", "r", stdin);
    freopen ("car.out", "w", stdout);
    read (N);
    for (int i = 1; i <= N; i ++)
    {
        read (point[i].x);
        read (point[i].y);
    }
    std :: sort (point + 1, point + 1 + N);

    int l, r, Mid;

    for (int i = 1; i <= N; i ++)
        for (int j = i + 1; j <= N; j ++)
        {
            if (point[i].x == point[j].x && point[i].y == point[j].y)
                continue ;
            if (Judge (point[i], point[j]))
                continue;
            register int now_x = (point[i].x + point[i].y + point[j].x - point[j].y) >> 1;
            register int now_y = (point[j].x - point[i].x + point[i].y + point[j].y) >> 1;
            l = 0;
            r = N + 1;
            while (l + 1 < r)
            {
                Mid = l + r >> 1;
                if (ErFen_Judge (Mid, now_x, now_y))
                    l = Mid;
                else
                    r = Mid;
            }
            int Result_1 = l;

            l = 0;
            r = N + 1;
            while (l + 1 < r)
            {
                Mid = l + r >> 1;
                if (ErFen_Re_Judge (Mid, now_x, now_y))
                    r = Mid;
                else
                    l = Mid;
            }
            Result_1 = l - Result_1;

            now_x = (point[i].x - point[i].y + point[j].x + point[j].y) >> 1;
            now_y = (point[i].x + point[i].y - point[j].x + point[j].y) >> 1;

            l = 0;
            r = N + 1;
            while (l + 1 < r)
            {
                Mid = l + r >> 1;
                if (ErFen_Judge (Mid, now_x, now_y))
                    l = Mid;
                else
                    r = Mid;
            }

            int Result_2 = l;

            l = 0;
            r = N + 1;
            while (l + 1 < r)
            {
                Mid = l + r >> 1;
                if (ErFen_Re_Judge (Mid, now_x, now_y))
                    r = Mid;
                else
                    l = Mid;
            }
            Result_2 = l - Result_2;
            Answer += (long long) Result_1 * Result_2;
        }
    printf ("%lld", Answer);
    return 0;
}

T3

  

    主席树 + 权值线段树 板子题。。

#include <algorithm>
#include <cstdio>

#define Max 40000

void read (int &now)
{
    now = 0;
    register char word = getchar ();
    while (word > ‘9‘ || word < ‘0‘)
        word = getchar ();
    while (word >= ‘0‘ && word <= ‘9‘)
    {
        now = now * 10 + word - ‘0‘;
        word = getchar ();
    }
}

void read_long_long (long long &now)
{
    now = 0;
    register char word = getchar ();
    while (word > ‘9‘ || word < ‘0‘)
        word = getchar ();
    while (word >= ‘0‘ && word <= ‘9‘)
    {
        now = now * 10 + word - ‘0‘;
        word = getchar ();
    }
}

struct Tree_Data
{
    int key;

    int l, r;
    int Mid;

};

Tree_Data tree[Max * 20];

Tree_Data node[Max];

int N, M;

class Tree_Type
{

    private :

        int Count_;
        int People_Count;

        void __Build_ (Tree_Data &now, int l, int r)
        {
            if (l == r)
                return ;
            now.Mid = l + r >> 1;
            now.l = ++ Count_;
            __Build_ (tree[now.l], l, now.Mid);
            now.r = ++ Count_;
            __Build_ (tree[now.r], now.Mid + 1, r);
        }

        void __Updata_ (Tree_Data &Pre, Tree_Data &now, int l, int r,int pos)
        {
            if (l == r)
            {
                now.key ++;
                return ;
            }
            now.Mid = Pre.Mid;
            if (pos <= now.Mid)
            {
                now.r = Pre.r;
                now.l = ++ Count_;
                __Updata_ (tree[Pre.l], tree[now.l], l, now.Mid, pos);
            }
            else
            {
                now.l = Pre.l;
                now.r = ++ Count_;
                __Updata_ (tree[Pre.r], tree[now.r], now.Mid + 1, r, pos);
            }
            now.key = tree[now.l].key + tree[now.r].key;
        }

        int __Query_ (Tree_Data &Pre, Tree_Data &now, int l, int r, int k)
        {
            if (l == r)
                return l;
            int res = tree[now.l].key - tree[Pre.l].key;
            if (k <= res)
                return __Query_ (tree[Pre.l], tree[now.l], l, now.Mid, k);
            else
                return __Query_ (tree[Pre.r], tree[now.r], now.Mid + 1, r, k - res);
        }

    public :

        Tree_Type ()
        {
            Count_ = 0;
            People_Count = 0;
        }

        inline void Build (int l, int r)
        {
            __Build_ (node[0], l, r);
            return ;
        }

        inline void Updata (int now, int pos)
        {
            __Updata_ (node[now - 1], node[now], 1, N, pos);
            return ;
        }

        inline int Query (int k)
        {
            return __Query_ (node[0], node[k], 1, N, ++ People_Count);
        }
};

Tree_Type President_Tree;

long long __rank[Max];
long long number[Max];

int main (int argc, char *argv[])
{
    freopen ("rollcall.in", "r", stdin);
    freopen ("rollcall.out", "w", stdout);

    read (N);
    read (M);
    for (int i = 1; i <= N; __rank[i] = number[i], i ++)
        read_long_long (number[i]);

    std :: sort (__rank + 1, __rank + 1 + N);
    int Size = std :: unique (__rank + 1, __rank + 1 + N) - __rank - 1;
    President_Tree.Build (1, N);

    for (int i = 1; i <= N; i ++)
    {
        number[i] = std :: lower_bound (__rank + 1, __rank + 1 + Size, number[i]) - __rank;
        President_Tree.Updata (i, number[i]);
    }

    for (int x; M --; )
    {
        read (x);
        printf ("%I64d\n", __rank[President_Tree.Query (x)]);
    }

    return 0;
}
时间: 2024-08-02 02:47:33

2017.6.11 校内模拟赛的相关文章

2017 9 11 noip模拟赛T2

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=205; int map[N][N]; int d[N],tag[N],book[N],f[N]; int n,m; void work(int x) { memset(d,63,sizeof(d)); memset(book,0,sizeof(book)); memset(f,0,sizeof(

2017.9.2 校内模拟赛

中规中矩的一套题. 然而辣鸡的我日常跪 卡SPFA是要哪样啊...再也不写SPFA了 100 + 0 + 70 = 170 "与" (and.pas/.c/.cpp) 时间限制:1s:空间限制64MB 题目描述: 给你一个长度为n的序列A,请你求出一对Ai,Aj(1<=i<j<=n)使Ai"与"Aj最大. Ps:"与"表示位运算and,在c++中表示为&. 输入描述: 第一行为n.接下来n行,一行一个数字表示Ai. 输出

校内模拟赛 Zbq&#39;s Music Challenge

Zbq's Music Challenge 题意: 一个长度为n的序列,每个位置可能是1或者0,1的概率是$p_i$.对于一个序列$S$,它的得分是 $$BasicScore=A\times \sum_{i=1}^{n}{S_i} \tag{1}$$ $$ combo(i)=\left\{ \begin{aligned} &S_i & &i=1 \\ &combo(i-1)+1 & &i\neq 1 ~\mathrm{and}~ S_i=1 \\ &

11.27 模拟赛

并没有人做的模拟赛... 出题人hx,,, T1:就是上一道矩阵乘法 数学题 T2: 一个数列中 一个区间满足,存在一个k(L <= k <= R),并且对于任意的i (L <= i <= R),ai都能被ak整除 这样的一个特殊区间 [L, R]价值为R - L 想知道序列中所有特殊区间的最大价值是多少,而有多少个这样的区间呢 这些区间又分别是哪些呢 输出每个区间的L 思路: 用两个ST表分别求一段区间的gcd和最小值 然后可以二分答案 check的时候枚举左端点,判断在这段区间

2017/11/3模拟赛

块(block)[问题描述]拼图达人小 C 手里有 n 个 1*1 的正方形方块, 他希望把这些方块拼在一起, 使得拼出的图形周长最小, 要求方块不能重叠. 擅长拼图的小 C 一下就求出了这个周长, 顺便他想考考你会不会求.[输入格式]多组数据, 第一行一个正整数 T, 表示数据组数.接下来 T 行, 每行一个正整数 n, 表示方块数.[输出格式]输出 T 行, 每行一个正整数, 表示答案.[样例输入]3 4 1122[样例输出]81420[数据范围]对于 20%的数据, n<=20:对于 40

2017/11/1模拟赛

磁星(magnet)[题目描述]在 B 城呆惯了的小 H 决定去外太空溜达一圈.人类现已发现并开发的星球(包括小 H 所在的星球)有 n 个,并且在这 n 个星球之中,人们发现了 m 对两个星球的关系.关系"xy"表示的是星球 x 对星球 y 有 1 一个单位的引导力,由于引导力还具有传递性,如果星球 x 对星球 y 能有恰好 a 个单位的引导力,星球y 对星球 z 能有恰好 b 个单位的引导力,那么星球 x 对星球 z 就能有恰好 a+b 个单位的引导力. 换言之,星球 x 对星球

2017 11 6模拟赛T1

作为一个毒瘤出题人(wzy:我不是毒瘤出题人,这些题明明很水的),wzy的题干十分复杂,但是把题意简化之后,相当简单粗暴... 求首项为1,等比为m,项数为t的等比数列的和,答案对k取模 不保证m与k互质 如果m与k互质的话,用等比数列的求和公式在求个逆元就能解决了,但是本题显然不能,于是必须考虑不含有除法的算法 于是就有了分治求等比数列和的办法. 设s(x)为等比数列的第n项 由等比数列的性质得到s(y)=s(x)*m^(y-x) (y>x) 将一个长度为2r的等比数列拆分成登场的两部分,对应

11.4 模拟赛

终于AK了,虽然第三题主要是搞月想出来的 T1: n个1*1的小方块,把这些小方块拼成一个图形,使这个图形周长最小 思路: 枚举拼成长方形的长为i,宽为n/i 可得面积 (i+n/i+(bool)(n%i))*2 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cmath> 6 #include<cstr

校内模拟赛:确定小组

  [问题描述] 有n个人坐成一排,这n个人都在某一个小组中,同一个小组的所有人所坐的位置一定是连续的. 有一个记者在现场进行采访,他每次采访都会询问一个人其所在的小组有多少人,被询问的每个人都给出了正确的答案,但是由于时间仓促,记者不一定询问了每个人,我们记录一个长度为n的答案序列,序列的第i个数表示第i个人的回答,如果为0则表示记者没有询问过这个人. 记者发现,对于一些情况,他可以唯一确定这排所有人的分组,而对于另外一些情况则不能,于是记者开始好奇,对于某一个答案序列,他能不能做到这一点,如