2022 纪中集训 7.16 笔记

T1 GMOJ 6277. 矩阵游戏

image

观察表格中的 \((i, j)\) 点可以表示为 \((i-1) \times m + j\)

由于列和行是相似的,这里只讨论行修改。

考虑推式子。

对于每一次行操作:

\[ans_r = \sum_{j=0}^{m} r_i \times [(i-1)\times + j] \]

\[= \sum_{j=0}^{m} [r_i \times (i-1) \times m + r_i \times j] \]

\[= \sum_{j=0}^{m} r_i \times (i-1) \times m + \sum_{j=0}^{m} r_i \times j \]

发现前半部分可以预处理, 后半部分可以将所有的 \(r_i\) 先加起来再算贡献。

点击查看代码
#include <bits/stdc++.h>

typedef long long LL;
using namespace std;

const LL N = 1000005;
const LL Mod = 1e9 + 7;

inline LL read()
{
    register LL x = 0, f = 1;
    register char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
    return x * f;
}

LL s[N],r[N];

int main()
{
	freopen("game.in","r",stdin);
	freopen("game.out","w",stdout);

    LL n = read(), m = read(), q = read();
	
	for (LL i=1;i<=n;++i) r[i] = 1;
	for (LL i=1;i<=m;++i) s[i] = 1;

	for (LL i=1;i<=q;++i)
	{
        char opt[2];
        scanf("%s",opt);

		LL x = read(), y = read();
		if (opt[0] == 'R') r[x] = (r[x]*y)%Mod; 
		if (opt[0] == 'S') s[x] = (s[x]*y)%Mod;
	} 

	LL sum1 = 0;
	for (LL i=1;i<=n;++i) sum1 = ((((r[i] * m) % Mod * (i-1)) % Mod) + sum1) % Mod;

    LL sum2 = 0;
	for (LL i=1;i<=n;++i) sum2 = (sum2 + r[i]) %Mod;

    LL ans = 0;
	for (LL j=1;j<=m;++j) ans = (ans + (sum1 + sum2 * j % Mod) % Mod * s[j] % Mod) % Mod;

    printf("%lld\n",ans);

    return 0;
}

T2 GMOJ 1385. 直角三角形

选择一个点 \(P\),并且平移平面直角坐标系使得 \(P\) 点与原点重合。

现在,对于每个点,先确定它在哪个象限里面。

然后将它顺时针旋转 \(90^{\circ}\),直至它位于第一象限。

在那之后,按照斜率将每个点排序

\(P\) 点能形成直角三角形的两个点,一定有着相同的斜率.

并且旋转前位于相邻的两个象限内。

排序之后,对于有着同样斜率的一组点,

统计四个象限内分别有多少个点,

并把相邻的象限的点的个数相乘即可得到答案.

点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

const int N = 1505;

int n;
LL ans;
int cnt[5];

struct Node
{
    LL x, y;
    int quadrant;
    bool operator< (const Node& t) const
    {
        return y * t.x < x * t.y;
    }
} a[N], b[N];

void rotate(int p)
{
    if (a[p].x == 0 && a[p].y == 0) return;
    a[p].quadrant = 1;  

    while (a[p].x <= 0 || a[p].y < 0)
    {
        swap(a[p].x, a[p].y);
        a[p].y = -a[p].y;
        a[p].quadrant++;
    }
}

int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%lld%lld", &b[i].x, &b[i].y);

    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            a[j].x = b[j].x - b[i].x;
            a[j].y = b[j].y - b[i].y;
            rotate(j);
        }

        swap(a[1], a[i]);
        sort(a + 2, a + n + 1);

        int j = 2;
        while (j <= n)
        {
            int k = j;
            memset(cnt, 0, sizeof cnt);

            while (k <= n && a[j].y * a[k].x == a[j].x * a[k].y)
            {
                cnt[a[k].quadrant]++;
                k++;
            }
            for (int t = 1; t <= 4; t++) ans += cnt[t] * cnt[t%4 + 1];
            j = k;
        }
    }

    printf("%lld", ans);

    return 0;
}
posted @ 2022-07-16 20:08  BorisDimitri  阅读(26)  评论(0编辑  收藏  举报