SDUT 3930 线段树
2024-09-04 15:15:52
皮卡丘的梦想2
Time Limit: 1000MS Memory Limit: 65536KB
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
%
%
题意:
有n个村庄,有最多60种石头,有三种操作:a b c ,a==1时表示b村庄加入第c种石头;a==2时表示b村庄移去第c种石头;a==3表示询问b到c村庄共有几种石头,输出石头的种类,如果没有石头输出%;
输入t组数据
输入n,m
输入m行操作
代码:
//第一次见这种的线段树,做题还是太少了。
//显然要用线段树,最多有60种石头,可以把他压缩一下,每个叶子节点存他有的石头的状态,更新时不过就是个位运算,
//然后就是个水题了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN=;
ll sum[MAXN];
void pushup(int rt){
sum[rt]=(sum[rt<<]|sum[rt<<|]);
}
void build(int l,int r,int rt){
if(l==r){
sum[rt]=;
return;
}
int mid=(l+r)>>;
build(l,mid,rt<<);
build(mid+,r,rt<<|);
pushup(rt);
}
void update(int id,int f,int c,int l,int r,int rt){
if(l==r){
ll tmp=(1LL<<c);
if(!(sum[rt]&tmp)&&f) sum[rt]|=tmp;
else if((sum[rt]&tmp)&&!f) sum[rt]^=tmp;
return;
}
int mid=(l+r)>>;
if(id<=mid) update(id,f,c,l,mid,rt<<);
else update(id,f,c,mid+,r,rt<<|);
pushup(rt);
}
ll query(int L,int R,int l,int r,int rt){
if(L<=l&&R>=r)
return sum[rt];
ll ans=;
int mid=(l+r)>>;
if(L<=mid)
ans|=query(L,R,l,mid,rt<<);
if(R>mid)
ans|=query(L,R,mid+,r,rt<<|);
return ans;
}
int main()
{
int t,n,m;
scanf("%d",&t);
for(int cas=;cas<=t;cas++){
scanf("%d%d",&n,&m);
int a,b,c;
build(,n,);
printf("Case %d:\n",cas);
for(int i=;i<m;i++){
scanf("%d%d%d",&a,&b,&c);
if(a==){
update(b,,c-,,n,);
}
else if(a==){
update(b,,c-,,n,);
}
else if(a==){
ll tmp=query(b,c,,n,);
int nu=,cnt[];
for(int i=;i<;i++){
if(tmp&(1LL<<i)) cnt[nu++]=i+;
}
if(nu==){
printf("%%\n");
continue;
}
sort(cnt,cnt+nu);
for(int i=;i<nu-;i++)
printf("%d ",cnt[i]);
printf("%d\n",cnt[nu-]);
}
}
}
return ;
}
最新文章
- vue.js+boostrap最佳实践
- PHP部分字符串函数汇总
- sed 使用 删除匹配行
- 12、在XAML中定义处理程序
- android logcat里面AndroidRuntime FATAL EXCEPTION: main这个是什么问题啊。
- HDU 1330 Nearest Common Ancestors(求两个点的近期公共祖先)
- 关于KeilC51的指针(参见, page 106-113, keil uv2 user&#39;s guide 09,2001)
- Effective Java2读书笔记-类和接口(四)
- bison实例
- MySQL加入log_bin报错
- sklearn svm基本使用
- -bash: _docker_machine_ps1: 未找到命令
- yii2 配合bootstrap添加按钮
- python的闭包与延时绑定问题
- 4.input()
- 架构图+kubernetes 问题理解 -- kube-pproxy - endpoint
- Eclipse之NDK编译-- Type &#39;jint&#39; could not be resolved, and JNIEnv, jclass错误解决办法
- 2.3 Oracle之DDL 语句(约束、伪列、视图、序列、同义词) 精简版
- 【转】Understanding the Angular Boot Process
- Java并发之ReentrantLock详解