zoukankan      html  css  js  c++  java
  • Gym100851A Adjustment Office 思维+模拟

    网址:https://codeforces.com/gym/100851

    题意:

    给你一个$n*n$的网格图,格子$(x,y)$的值是$x+y$,有两种操作:

    $R$ $c$:输出第$R$列的和,然后这一列所有的数置零。

    $C$ $c$:输出第$C$行的和,然后这一行所有的数置零。

    一共$q$次操作。

    $n leq 1e6,q leq 1e5$。

    题解:

    这个题我们考虑先预处理出这个网格图每一行每一列的和,逐个暴力求$O(n^2)$必超时,考虑求出了第一行第一列的和,显然下一行的和为这一行的和加上$n$。$O(n)$就能递推出结果。然后考虑一次操作一。如果这一列已经空了,输出$0$即可,如果没有,先观察有多少行的和已经是$0$了,这一列的实际的和就是:原来求出的和$-$(和为$0$的行的行号的和$+$这一列的列号$*$和为$0$的行的数量),然后把这一列的和记为$0$。然后记录下来。对操作二同理。

    注意:所有参加计算的值都需要$long$ $long$,否则会溢出。

    AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e6 + 5;
    typedef long long ll;
    vector<ll>rd, cd;
    ll rdsum, cdsum;
    ll rsum[N], csum[N];
    int main()
    {
    	freopen("adjustment.in", "r", stdin);
    	freopen("adjustment.out", "w", stdout);
    	ll n, q;//这里不用ll应该也可,但是不值得冒这个险
    	scanf("%lld%lld", &n, &q);
    	rsum[1] = (2ll + n + 1ll) * n / 2;
    	for (int i = 2; i <= n; ++i)
    		rsum[i] = rsum[i - 1] + n;
    	for (int i = 1; i <= n; ++i)
    		csum[i] = rsum[i];
    	char op[2];
    	ll p = 0;//p不用ll会溢出
    	for (int i = 1; i <= q; ++i)
    	{
    		scanf("%s%lld", op, &p);
    		if (op[0] == 'R')
    		{
    			if (!rsum[p])
    				printf("0
    ");
    			else
    			{
    				rdsum += p;
    				printf("%lld
    ", rsum[p] - (ll)cd.size() * p - cdsum);
    				rsum[p] = 0;
    				rd.push_back(p);
    			}
    		}
    		else if (op[0] == 'C')
    		{
    			if (!csum[p])
    				printf("0
    ");
    			else
    			{
    				cdsum += p;
    				printf("%lld
    ", csum[p] - (ll)rd.size() * p - rdsum);
    				csum[p] = 0;
    				cd.push_back(p);
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    HUAS 1482 lsy的后宫(DP+矩阵快速幂)
    HUAS 1483 mex(离线+线段树)
    oracle 分页
    oracle 表查询(二)
    oracle 表查询(一)
    oracle 表的管理
    oracle 用户管理
    oracle sql*plus常用命令
    挑选数据库
    oracle sequence用法
  • 原文地址:https://www.cnblogs.com/Aya-Uchida/p/12588727.html
Copyright © 2011-2022 走看看