ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[NOIP2016 普及组] 魔法阵

2022-03-20 08:02:04  阅读:199  来源: 互联网

标签:NOIP2016 普及 tong int sum 魔法阵 lt include


洛谷题面

题目大意

给定 \(n,m\) 和 \(m\) 个整数 \(x_i\),\(1\le x_i\le n\)。

如果存在四元组 \((a,b,c,d)\) 满足:

  • \(x_a<x_b<x_c<x_d\)

  • \(x_b-x_a=2\times (x_d-x_c)\)

  • \(x_b-x_a<(x_c-x_b)/3\)

那么这个四元组是有效的,问每个物品分别作为有效四元组中 \(a,b,c,d\) 几次。

题目分析

根据题意可知需要满足三个条件:

  • \(x_a<x_b<x_c<x_d\) \(~(1)\)

  • \(x_b-x_a=2\times (x_d-x_c)\) \(~(2)\)

  • \(x_b-x_a<(x_c-x_b)/3~\)\((3)\)

令 \(t=x_d-x_c\),所以:

代入 \((2)\) 可得:\(x_b-x_a=2t\)\(~(4)\)

将 \((4)\) 代入 \((3)\) 可得:\(2t\lt (x_c-x_b)/3=6t\lt x_c-x_b\)\(~(5)\)

改一下 \((5)\):\(6t+k=x_c-x_b(k\gt 0)\) \(~(6)\)

根据 \((6)\) 画图可得:(直接用的 这篇题解 的图)

1113423-20180801210708340-1039644464.png

可以看出 \(A\) 的最小值为 \(1\),\(D\) 的最大值为 \(n\)。因此我们尝试枚举 \(t\),因为 \(AD=9t+k\),所以 \(t\) 的范围是 \(t\le (n-1)/9=9t\lt n\)。

然后枚举易掌控的右界即 \(D\),可以表示出 \(C=D-t\),\(A,B\) 的最大值为 \(D-9t-1\) 和 \(D-7t-1\)。

但 \(A,B\) 变小就不好直接控制了,观察到只要 \(x_c-x_b\gt 6t\),那么这个魔法阵一定存在,故当 \(a_1\lt a_2,b_1\lt b_2\) 时,若 \(a_2,b_2\) 与 \(C,D\) 组成魔法阵,那么 \(a_1,b_1\) 与 \(C,D\) 也可以组成魔法阵。所以可以使用前缀和优化。

同理枚举 \(A\),使用后缀和优化就好了。

代码

//2022/3/18
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <climits>//need "INT_MAX","INT_MIN"
#include <cstring>//need "memset"
#include <numeric>
#include <algorithm>
#define enter putchar(10)
#define debug(c,que) cerr << #c << " = " << c << que
#define cek(c) puts(c)
#define blow(arr,st,ed,w) for(register int i = (st);i <= (ed); ++ i) cout << arr[i] << w;
#define speed_up() cin.tie(0),cout.tie(0)
#define mst(a,k) memset(a,k,sizeof(a))
#define Abs(x) ((x) > 0 ? (x) : -(x))
const int mod = 1e9 + 7;
inline int MOD(int x) {
    if(x < 0) x += mod;
    return x % mod;
}
namespace Newstd {
    char buf[1 << 21],*p1 = buf,*p2 = buf;
    inline int getc() {
        return p1 == p2 && (p2 = (p1 = buf) + fread(buf,1,1 << 21,stdin),p1 == p2) ? EOF : *p1 ++;
    }
    inline int read() {
        int ret = 0,f = 0;char ch = getc();
        while (!isdigit(ch)) {
            if(ch == '-') f = 1;
            ch = getc();
        }
        while (isdigit(ch)) {
            ret = (ret << 3) + (ret << 1) + ch - 48;
            ch = getc();
        }
        return f ? -ret : ret;
    }
    inline void write(int x) {
        if(x < 0) {
            putchar('-');
            x = -x;
        }
        if(x > 9) write(x / 10);
        putchar(x % 10 + '0');
    }
}
using namespace Newstd;
using namespace std;

const int ma1 = 1.5e4 + 5,ma2 = 4e4 + 5;
int tong[ma1],a[ma2],matrix[ma2][5];
int n,m;
int main(void) {
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    n = read(),m = read();
    for (register int i = 1;i <= m; ++ i) {
        a[i] = read();
        tong[a[i]] ++;
    }
    for (register int t = 1,sum;t * 9 < n; ++ t) {
        sum = 0;
        for (register int A = n - 9 * t - 1;A >= 1; -- A) {
            int B = A + 2 * t;
            int C = A + 8 * t + 1;
            int D = A + 9 * t + 1;
            sum += tong[C] * tong[D];
            matrix[A][1] += sum * tong[B],matrix[B][2] += sum * tong[A];
        }
        sum = 0;
        for (register int D = 9 * t + 2;D <= n; ++ D) {
            int A = D - 9 * t - 1;
            int B = A + 2 * t;
            int C = D - t;
            sum += tong[A] * tong[B];
            matrix[C][3] += sum * tong[D],matrix[D][4] += sum * tong[C];
        }
    }
    for (register int i = 1;i <= m; ++ i) {
        for (register int j = 1;j <= 4; ++ j) {
            printf("%d ",matrix[a[i]][j]);
        }
        enter;
    }

    return 0;
}

标签:NOIP2016,普及,tong,int,sum,魔法阵,lt,include
来源: https://www.cnblogs.com/Coros-Trusds/p/16028915.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有