题目链接:点击打开链接
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;
}