Problem Description
一天,一只住在 501 实验室的皮卡丘决定发奋学习,成为像 LeiQ 一样的巨巨,于是他向镇上的贤者金桔请教如何才能进化成一只雷丘。
金桔告诉他需要进化石才能进化,并给了他一个地图,地图上有 n 个小镇,他需要从这些小镇中收集进化石。
接下来他会进行 q 次操作,可能是打听进化石的信息,也可能是向你询问第 l 个小镇到第 r 个小镇之间的进化石种类。
如果是打听信息,则皮卡丘会得到一个小镇的进化石变化信息,可能是引入了新的进化石,也可能是失去了全部的某种进化石。
如果是向你询问,你需要回答他第 l 个小镇到第 r 个小镇之间的进化石种类。
Input
首先输入一个整数 T (1 <= T <= 10),代表有 T 组数据。
每组数据的第一行输入一个整数 n (1 <= n <= 100000) 和一个整数 q (1 <= q <= 100000),分别代表有 n 个小镇,表皮卡丘有 q 次操作。
接下来输入 q 行,对于每次操作,先输入操作类型,然后根据操作类型读入:
- 1: 紧接着输入 2 个整数 a (1 <= a <= n), b (1 <= b <= 60),表示第 a 个小镇引入了第 b 种进化石
- 2: 紧接着输入 2 个整数 a (1 <= a <= n), b (1 <= b <= 60),表示第 a 个小镇失去了全部第 b 种进化石
- 3: 紧接着输入 2 个整数 l, r (1 <= l <= r <= n),表示他想询问从第 l 个到第 r 个小镇上可收集的进化石有哪几种
Output
对于每组输入,首先输出一行 "Case T:",表示当前是第几组数据。
对于每组数据中的每次 3 操作,在一行中按编号升序输出所有可收集的进化石。如果没有进化石可收集,则输出一个 MeiK 的百分号 "%"(不包括引号)。
Example Input
1 10 10 3 1 10 1 1 50 3 1 5 1 2 20 3 1 1 3 1 2 2 1 50 2 2 20 3 1 2 3 1 10
Example Output
Case 1: % 50 50 20 50 % %
Code:
#include <bits/stdc++.h>
#define LL long long
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
using namespace std;
const int maxn = 100005;
LL c[maxn<<2], ans;
int n, q, opt[65];
void pushUp(int rt)
{
c[rt] = c[rt<<1]|c[rt<<1|1];
}
void update(int cz, int key, int cur, int l, int r, int rt)
{
if(l == r)
{
if(key) c[rt] |= (1ll<<cz);
else c[rt] &= ~(1ll<<cz);
return;
}
int m = (l+r) >> 1;
if(m >= cur) update(cz, key, cur, lson);
else update(cz, key, cur, rson);
pushUp(rt);
}
void query(int L, int R, int l, int r, int rt)
{
if(L <= l && R >= r)
{
ans |= c[rt];
return;
}
int m = (l+r)>>1;
if(L <= m) query(L, R, lson);
if(R > m) query(L, R, rson);
}
int main()
{
int t, q1, q2, q3, count = 0;
scanf("%d", &t);
while(t--)
{
scanf("%d %d", &n, &q);
printf("Case %d:\n", ++count);
memset(c, 0, sizeof c);
for(int i = 1; i <= q; ++i)
{
scanf("%d %d %d", &q1, &q2, &q3);
if(q1 == 1) update(q3, 1, q2, 1, n, 1);
if(q1 == 2) update(q3, 0, q2, 1, n, 1);
if(q1 == 3)
{
ans = 0;
query(q2, q3, 1, n, 1);
int tot = 0;
for(int i = 1; i <= 60; ++i)
if((1ll<<i)&ans) opt[tot++] = i;
if(!tot) printf("%\n");
else
{
for(int i = 0; i < tot; ++i)
{
if(i != 0) printf(" ");
printf("%d", opt[i]);
}
printf("\n");
}
}
}
}
return 0;
}
继续加油~