HDOJ5475 An easy problem(暴力 & 线段树)

12 篇文章 0 订阅
9 篇文章 0 订阅

题目链接:点击打开链接


t组样例,每组第一行给出q, m,q次操作,每次包含x, y,为1则乘y对m取模,为2则除y对m取模,除的时候保证y在前面乘的操作中出现过。

注意数据范围,直接暴力或者线段树单点更新都可行。

比赛时又t又wa的,4个小时愣是没想出来,这就是陷进一道题的危害,要懂得舍,才会有得!有时候自己把问题想的太麻烦了,明日

加油!为我队鼓气!


AC代码(暴力):

#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
const int MAXN = 1e5 + 5;
typedef long long ll;
ll a[MAXN], m;
int q, op;
int main(int argc, char const *argv[])
{
    int t;
    scanf("%d", &t);
    for(int cas = 1; cas <= t; ++cas) {
        printf("Case #%d:\n", cas);
        scanf("%d%lld", &q, &m);
        ll ans = 1;
        for(int i = 1; i <= q; ++i) {
            scanf("%d%lld", &op, &a[i]);
            if(op == 1) ans = ans * a[i] % m;
            else {
                a[a[i]] = 1, a[i] = 1, ans = 1;
                for(int j = 1; j < i; ++j)
                    ans = ans * a[j] % m;
            }
            printf("%lld\n", ans);
        }
    }
    return 0;
}


AC代码(线段树):

#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
using namespace std;
const int MAXN = 1e5 + 5;
typedef long long ll;
#define lson l, mid, x << 1
#define rson mid + 1, r, x << 1 | 1
struct node
{
	/* data */
	ll l, r, sum;
}a[MAXN << 2];
ll m, y, flag[MAXN];
int q, op;
void push_up(ll x)
{
	a[x].sum = (a[x << 1].sum * a[x << 1 | 1].sum) % m;
} 
void build(ll l, ll r, ll x)
{
	a[x].sum = 1, a[x].l = l, a[x].r = r;
	if(l == r) {
		a[x].sum = 1;
		return;
	}
	ll mid = (l + r) >> 1;
	build(lson);
	build(rson);
}
void updata(ll l, ll r, ll x, ll k)
{
	if(l == a[x].l && r == a[x].r) {
		a[x].sum = k;
		return;
	}
	ll mid = (a[x].l + a[x].r) >> 1;
	if(r <= mid) updata(l, r, x << 1, k);
	else if(l > mid) updata(l, r, x << 1 | 1, k);
	else {
		updata(lson, k);
		updata(rson, k);
	}
	push_up(x);
}
int main(int argc, char const *argv[])
{
	int t;
	scanf("%d", &t);
	for(int cas = 1; cas <= t; ++cas) {
		memset(a, 0, sizeof(a));
		printf("Case #%d:\n", cas);
		scanf("%d%lld", &q, &m);
		build(1, q, 1);
		ll tem = 1;
		for(int i = 1; i <= q; ++i) {
			scanf("%d%lld", &op, &y);
			if(op == 1) {
				updata(tem, tem, 1, y);
				printf("%lld\n", a[1].sum % m);
				flag[i] = tem;
				tem++;
			}
			else {
				updata(flag[y], flag[y], 1, 1);
				printf("%lld\n", a[1].sum % m);
			}
		}
	}
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值