Tyvj P2068(寻宝)

P2068 - [NOIP2012P2]寻宝

From luchangzhou    Normal (OI)
总时限:10s    内存限制:128MB    代码长度限制:64KB

背景 Background

NOIP 2012 普及组 题2

描述 Description

传说很遥远的藏宝楼顶层藏着诱人的宝藏。小明历尽千辛万苦终于找到传说中的这个藏 宝楼,藏宝楼的门口竖着一个木板,上面写有几个大字:寻宝说明书。说明书的内容如下: 藏宝楼共有 N+1 层,最上面一层是顶层,顶层有一个房间里面藏着宝藏。除了顶层外, 藏宝楼另有 N 层,每层 M 个房间,这 M 个房间围成一圈并按逆时针方向依次编号为 0,…, M-1。其中一些房间有通往上一层的楼梯,每层楼的楼梯设计可能不同。每个房间里有一个 指示牌,指示牌上有一个数字 x,表示从这个房间开始按逆时针方向选择第 x 个有楼梯的房 间(假定该房间的编号为 k),从该房间上楼,上楼后到达上一层的 k 号房间。比如当前房 间的指示牌上写着 2,则按逆时针方向开始尝试,找到第 2 个有楼梯的房间,从该房间上楼。 如果当前房间本身就有楼梯通向上层,该房间作为第一个有楼梯的房间。

寻宝说明书的最后用红色大号字体写着:“寻宝须知:帮助你找到每层上楼房间的指示 牌上的数字(即每层第一个进入的房间内指示牌上的数字)总和为打开宝箱的密钥”。

请帮助小明算出这个打开宝箱的密钥。

输入格式 InputFormat

第一行 2 个整数 N 和 M,之间用一个空格隔开。N 表示除了顶层外藏宝楼共 N 层楼,M 表示除顶层外每层楼有 M 个房间。

       接下来 N*M 行,每行两个整数,之间用一个空格隔开,每行描述一个房间内的情况, 其中第(i-1)*M+j 行表示第 i 层 j-1 号房间的情况(i=1, 2, …, N;j=1, 2, … ,M)。第一个整数 表示该房间是否有楼梯通往上一层(0 表示没有,1 表示有),第二个整数表示指示牌上的数 字。注意,从 j 号房间的楼梯爬到上一层到达的房间一定也是 j 号房间。

      最后一行,一个整数,表示小明从藏宝楼底层的几号房间进入开始寻宝(注:房间编号 从 0 开始)。

输出格式 OutputFormat

输出只有一行,一个整数,表示打开宝箱的密钥,这个数可能会很大,请输出对 20123取模的结果即可。

样例输入 SampleInput [复制数据]

2 3
1 2
0 3
1 4
0 1
1 5
1 2
1

样例输出 SampleOutput [复制数据]

5

数据范围和注释 Hint

【输入输出样例说明】

第一层:

0 号房间,有楼梯通往上层,指示牌上的数字是 2;

1 号房间,无楼梯通往上层,指示牌上的数字是 3;

2 号房间,有楼梯通往上层,指示牌上的数字是 4;

第二层:

0 号房间,无楼梯通往上层,指示牌上的数字是 1;

1 号房间,有楼梯通往上层,指示牌上的数字是 5;

2 号房间,有楼梯通往上层,指示牌上的数字是 2;

小明首先进入第一层(底层)的 1 号房间,记下指示牌上的数字为 3,然后从这个房间 开始,沿逆时针方向选择第 3 个有楼梯的房间 2 号房间进入,上楼后到达第二层的 2 号房间, 记下指示牌上的数字为 2,由于当前房间本身有楼梯通向上层,该房间作为第一个有楼梯的 房间。因此,此时沿逆时针方向选择第 2 个有楼梯的房间即为 1 号房间,进入后上楼梯到达 顶层。这时把上述记下的指示牌上的数字加起来,即 3+2=5,所以打开宝箱的密钥就是 5。

【数据范围】

对于 50%数据,有 0<N≤1000,0<x≤10000;

对于 100%数据,有 0<N≤10000,0<M≤100,0<x≤1,000,000;

来源 Source

NOIP 2012

纯粹的模拟题,由于x很大但M很小,可以%tot[i]

但是这么做可能变为0.



#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<cctype>
#include<functional>
#include<algorithm>
using namespace std;
#define MAXN (10000+10)
#define MAXM (100+10)
#define MAXX (1000000+10)
#define F (20123)
#define NDEBUG
int n,m;
int a[MAXN][MAXM],tot[MAXN]={0};
bool b[MAXN][MAXM]={0};
int main()
{
	#ifndef NDEBUG
	freopen("wealth.in","r",stdin);
	#endif
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++)
		for (int j=0;j<=m-1;j++)
		{
			scanf("%d%d",&b[i][j],&a[i][j]);
			tot[i]+=b[i][j];
		}
	#ifndef NDEBUG
	for (int i=1;i<=n;i++) cout<<tot[i]<<' ';
	#endif
	int x,ans=0;
	scanf("%d",&x);
	for (int i=1;i<=n;i++)
	{
		ans=(ans+a[i][x])%F;
		int len=a[i][x]%tot[i];
		if (len==0) len=tot[i];
		while(len)
		{
			len-=b[i][x];
			if (len==0) break;
			x=(x+1)%m;
		}
	}
//	cout<<x<<endl;
	cout<<ans<<endl;
	return 0;
}

国家集训队论文分类整理

距离ACM/ICPC的时间越来越少了,选择性地看一些集训队论文是很有必要的。

组合数学 计数与统计 2001 - 符文杰:《Pólya原理及其应用》
2003 - 许智磊:《浅谈补集转化思想在统计问题中的应用》
2007 - 周冬:《生成树的计数及其应用》
2008 - 陈瑜希《Pólya计数法的应用》
数位问题 2009 - 高逸涵《数位计数问题解法研究》
2009 - 刘聪《浅谈数位类统计问题》
动态统计 2004 - 薛矛:《解决动态统计问题的两把利刃》
2007 - 余江伟:《如何解决动态统计问题》
博弈 2002 - 张一飞:《由感性认识到理性认识——透析一类搏弈游戏的解答过程》
2007 - 王晓珂:《解析一类组合游戏》
2009 - 曹钦翔《从“k倍动态减法游戏”出发探究一类组合游戏问题》
2009 - 方展鹏《浅谈如何解决不平等博弈问题》
2009 - 贾志豪《组合游戏略述——浅谈SG游戏的若干拓展及变形》
母函数 2009 - 毛杰明《母函数的性质及应用》
拟阵 2007 - 刘雨辰:《对拟阵的初步研究》
线性规划 2007 - 李宇骞:《浅谈信息学竞赛中的线性规划——简洁高效的单纯形法实现与应用》
置换群 2005 - 潘震皓:《置换群快速幂运算研究与探讨》
问答交互 2003 - 高正宇:《答案只有一个——浅谈问答式交互问题》 
猜数问题 2003 - 张宁:《猜数问题的研究:<聪明的学生>一题的推广》
2006 - 龙凡:《一类猜数问题的研究》
数据结构 数据结构 2005 - 何林:《数据关系的简化》
2006 - 朱晨光:《基本数据结构在信息学竞赛中的应用》
2007 - 何森:《浅谈数据的合理组织》
2008 - 曹钦翔《数据结构的提炼与压缩》
结构联合 2001 - 高寒蕊:《从圆桌问题谈数据结构的综合运用》
2005 - 黄刚:《数据结构的联合》
块状链表 2005 - 蒋炎岩:《数据结构的联合——块状链表》
2008 - 苏煜《对块状链表的一点研究》
动态树 2006 - 陈首元:《维护森林连通性——动态树》
2007 - 袁昕颢:《动态树及其应用》
左偏树 2005 - 黄源河:《左偏树的特点及其应用》
跳表 2005 - 魏冉:《让算法的效率“跳起来”!——浅谈“跳跃表”的相关操作及其应用》
2009 - 李骥扬《线段跳表——跳表的一个拓展》
SBT 2007 - 陈启峰:《Size Balance Tree》
线段树 2004 - 林涛:《线段树的应用》
单调队列 2006 - 汤泽:《浅析队列在一类单调性问题中的应用》
哈希表 2005 - 李羽修:《Hash函数的设计优化》
2007 - 杨弋:《Hash在信息学竞赛中的一类应用》
Splay 2004 - 杨思雨:《伸展树的基本操作与应用》
图论 图论 2005 - 任恺:《图论的基本思想及方法》
模型建立 2004 - 黄源河:《浅谈图论模型的建立与应用》
2004 - 肖天:《“分层图思想”及其在信息学竞赛中的应用》
网络流 2001 - 江鹏:《从一道题目的解法试谈网络流的构造与算法》
2002 - 金恺:《浅谈网络流算法的应用》
2007 - 胡伯涛:《最小割模型在信息学竞赛中的应用》
2007 - 王欣上:《浅谈基于分层思想的网络流算法》
2008 - 周冬《两极相通——浅析最大—最小定理在信息学竞赛中的应用》
最短路 2006 - 余远铭:《最短路算法及其应用》
2008 - 吕子鉷《浅谈最短径路问题中的分层思想》
2009 - 姜碧野《SPFA算法的优化及应用》
欧拉路 2007 - 仇荣琦:《欧拉回路性质与应用探究》
差分约束系统 2006 - 冯威:《数与图的完美结合——浅析差分约束系统》
平面图 2003 - 刘才良:《平面图在信息学中的应用》
2007 - 古楠:《平面嵌入》
2-SAT 2003 - 伍昱:《由对称性解2-SAT问题》
最小生成树 2004 - 吴景岳:《最小生成树算法及其应用》
2004 - 汪汀:《最小生成树问题的拓展》
二分图 2005 - 王俊:《浅析二分图匹配在信息学竞赛中的应用》
Voronoi图 2006 - 王栋:《浅析平面Voronoi图的构造及应用》
偶图 2002 - 孙方成:《偶图的算法及应用》
2002 - 周文超:《树结构在程序设计中的运用》
2005 - 栗师:《树的乐园——一些与树有关的题目》
路径问题 2009 - 漆子超《分治算法在树的路径问题中的应用》
最近公共祖先 2007 - 郭华阳:《RMQ与LCA问题》
划分问题 2004 - 贝小辉:《浅析树的划分问题》
数论 欧几里得算法 2009 - 金斌《欧几里得算法的应用》
同余方程 2003 - 姜尚仆:《模线性方程的应用——用数论方法解决整数问题》
搜索 搜索 2001 - 骆骥:《由“汽车问题”浅谈深度搜索的一个方面——搜索对象与策略的重要性》
2002 - 王知昆:《搜索顺序的选择》
2005 - 汪汀:《参数搜索的应用》
启发式 2009 - 周而进《浅谈估价函数在信息学竞赛中的应用》
优化 2003 - 金恺:《探寻深度优先搜索中的优化技巧——从正方形剖分问题谈起》
2003 - 刘一鸣:《一类搜索的优化思想——数据有序化》
2006 - 黄晓愉:《深度优先搜索问题的优化技巧》
背包问题 2009 - 徐持衡《浅谈几类背包题》
匹配 2004 - 楼天城:《匹配算法在搜索问题中的巧用》
概率 概率 2009 - 梅诗珂《信息学竞赛中概率问题求解初探》
数学期望 2009 - 汤可因《浅析竞赛中一类数学期望问题的解决方法》
字符串 字符串 2003 - 周源:《浅析“最小表示法”思想在字符串循环同构问题中的应用》
多串匹配 2004 - 朱泽园:《多串匹配算法及其启示》
2006 - 王赟:《Trie图的构建、活用与改进》
2009 - 董华星《浅析字母树在信息学竞赛中的应用》
后缀数组 2004 - 许智磊:《后缀数组》
2009 - 罗穗骞《后缀数组——处理字符串的有力工具》
字符串匹配 2003 - 饶向荣:《病毒的DNA———剖析一道字符匹配问题解析过程》
2003 - 林希德:《求最大重复子串》
动态规划 动态规划 2001 - 俞玮:《基本动态规划问题的扩展》
2006 - 黄劲松:《贪婪的动态规划》
2009 - 徐源盛《对一类动态规划问题的研究》
状态压缩 2008 - 陈丹琦《基于连通性状态压缩的动态规划问题》
状态设计 2008 - 刘弈《浅谈信息学中状态的合理设计与应用》
树形DP 2007 - 陈瑜希:《多角度思考创造性思维——运用树型动态规划解题的思路和方法探析》
优化 2001 - 毛子青:《动态规划算法的优化技巧》
2003 - 项荣璟:《充分利用问题性质——例析动态规划的“个性化”优化》
2004 - 朱晨光:《优化,再优化!——从《鹰蛋》一题浅析对动态规划算法的优化》
2007 - 杨哲:《凸完全单调性的加强与应用》
计算几何 立体几何 2003 - 陆可昱:《长方体体积并》
2008 - 高亦陶《从立体几何问题看降低编程复杂度》
计算几何思想 2004 - 金恺:《极限法——解决几何最优化问题的捷径》
2008 - 程芃祺《计算几何中的二分思想》
2008 - 顾研《浅谈随机化思想在几何问题中的应用》
2007 - 高逸涵:《与圆有关的离散化》
半平面交 2002 - 李澎煦:《半平面交的算法及其应用》
2006 - 朱泽园:《半平面交的新算法及其实用价值》
矩阵 矩阵 2008 - 俞华程《矩阵乘法在信息学中的应用》
高斯消元 2002 - 何江舟:《用高斯消元法解线性方程组》
数学方法 数学思想 2002 - 何林:《猜想及其应用》
2003 - 邵烜程:《数学思想助你一臂之力》
数学归纳法 2009 - 张昆玮《数学归纳法与解题之道》
多项式 2002 - 张家琳:《多项式乘法》
数形结合 2004 - 周源:《浅谈数形结合思想在信息学竞赛中的应用》
黄金分割 2005 - 杨思雨:《美,无处不在——浅谈“黄金分割”和信息学的联系》
其他算法 遗传算法 2002 - 张宁:《遗传算法的特点及其应用》
2005 - 钱自强:《关于遗传算法应用的分析与研究》
信息论 2003 - 侯启明:《信息论在信息学竞赛中的简单应用》
染色与构造 2002 - 杨旻旻:《构造法——解题的最短路径》
2003 - 方奇:《染色法和构造法在棋盘上的应用》
一类问题 区间 2008 - 周小博《浅谈信息学竞赛中的区间问题》
2005 - 龙凡:《序的应用》
2006 - 汪晔:《信息学中的参考系与坐标系》
物理问题 2008 - 方戈《浅析信息学竞赛中一类与物理有关的问题》
编码与译码 2008 - 周梦宇《码之道—浅谈信息学竞赛中的编码与译码问题》
对策问题 2002 - 骆骥:《浅析解“对策问题”的两种思路》
优化 算法优化 2002 - 孙林春:《让我们做得更好——从解法谈程序优化》
2004 - 胡伟栋:《减少冗余与算法优化》
2005 - 杨弋:《从<小H的小屋>的解法谈算法的优化》
2006 - 贾由:《由图论算法浅析算法优化》
程序优化 2006 - 周以苏:《论反汇编在时间常数优化中的应用》
2009 - 骆可强《论程序底层优化的一些方法与技巧》
语言 C++ 2004 - 韩文弢:《论C++语言在信息学竞赛中的应用》
策略 策略 2004 - 李锐喆:《细节——不可忽视的要素》
2005 - 朱泽园:《回到起点——一种突破性思维》
2006 - 陈启峰:《“约制、放宽”方法在解题中的应用》
2006 - 李天翼:《从特殊情况考虑》
2007 - 陈雪:《问题中的变与不变》
2008 - 肖汉骏《例谈信息学竞赛分析中的“深”与“广”》
倍增 2005 - 朱晨光:《浅析倍增思想在信息学竞赛中的应用》
二分 2002 - 李睿:《二分法与统计问题》
2002 - 许智磊:《二分,再二分!——从Mobiles(IOI2001)一题看多重二分》
2005 - 杨俊:《二分策略在信息学竞赛中的应用》
调整 2006 - 唐文斌:《“调整”思想在信息学中的应用》
随机化 2007 - 刘家骅:《浅谈随机化在信息学竞赛中的应用》
非完美算法 2005 - 胡伟栋:《浅析非完美算法在信息学竞赛中的应用》
2008 - 任一恒《非完美算法初探》
提交答案题 2003 - 雷环中:《结果提交类问题》
守恒思想 2004 - 何林:《信息学中守恒法的应用》
极限法 2003 - 王知昆:《浅谈用极大化思想解决最大子矩形问题》
贪心 2008 - 高逸涵《部分贪心思想在信息学竞赛中的应用》
压缩法 2005 - 周源:《压去冗余缩得精华——浅谈信息学竞赛中的“压缩法”》
逆向思维 2005 - 唐文斌:《正难则反——浅谈逆向思维在解题中的应用》
穷举 2004 - 鬲融:《浅谈特殊穷举思想的应用》
目标转换 2002 - 戴德承:《退一步海阔天空——“目标转化思想”的若干应用》
2004 - 栗师:《转化目标在解题中的应用》
类比 2006 - 周戈林:《浅谈类比思想》
分割与合并 2006 - 俞鑫:《棋盘中的棋盘——浅谈棋盘的分割思想》
2007 - 杨沐:《浅析信息学中的“分”与“合”》
平衡思想 2008 - 郑暾《平衡规划——浅析一类平衡思想的应用》

CF 1A(隐式转换)

A. Theatre Square
time limit per test

2 seconds

memory limit per test

64 megabytes

input

standard input

output

standard output

在n*m的广场上平铺边长为a的正方形石板,问至少要多少石板才能铺满广场(石板必须对齐且与边角线平行)

Input

输入仅一行 n,  m and a (1 ≤  n, m, a ≤ 109).

Output

输出一行最小石板数。

Sample test(s)
input
6 6 4
output
4

显然答案为(ceil(double(n)/double(a))*ceil(double(m)/double(a)))。

但直接用cout输出可能被转换成科学表示法

且极端情况Maxn*Maxm>2^31

所以输出时要打上(long long)

而且必须框上double()否则中间的‘/'会被当成整除


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
using namespace std;
#define MAXN (1000000000)
long long n,m,a;
int main()
{
	cin>>n>>m>>a;
	cout<<(long long)(ceil(double(n)/double(a))*ceil(double(m)/double(a)))<<endl;
	return 0;
}

Tyvj P1180(情况少分支多的过程-Dp)

P1180 - 矿工配餐

From Admin    Normal (OI)
总时限:16s    内存限制:128MB    代码长度限制:64KB

描述 Description

现有两个煤矿,每个煤矿都雇用一组矿工。采煤工作很辛苦,所以矿工们需要良好饮食。每当一辆食品车到达煤矿时,矿工们便会产出一定数量的煤。有三种类型的食品车:肉车,鱼车和面包车。
矿工们喜欢变化的食谱。如果提供的食品能够不断变化,他们的产煤量将会增加。每当一个新的食品车到达煤矿时,矿工们就会比较这种新的食品和前两次(或者少于两次,如果前面运送食品的次数不足两次)的食品,并且:
如果这几次食品车都是同一类型的食品,则矿工们产出一个单位的煤。
如果这几次食品车中有两种不同类型的食品,则矿工们产出两个单位的煤。
如果这几次食品车中有三种不同类型的食品,则矿工们产出三个单位的煤。
预先已知食品车的类型及其被配送的顺序。通过确定哪车食品送到哪个煤矿可以影响产煤量。食品车不能被拆分,每个食品车必须被全部送到一个或另一个煤矿。两个煤矿也并不要求接收相同数量的食品车(事实上,也允许将所有食品车都送到一个煤矿)。
任务
给出食品车的类型及其被配送的顺序,要求你写一个程序,确定哪个食品车应被送到煤矿1,哪个食品车应被送到煤矿2,以使得两个煤矿的产煤量的总和最大。

输入格式 InputFormat

输入的第一行包含一个整数N (1 ≤ N ≤ 100 000),  表示食品车的数目。
第二行包含一个由N个字符组成的字符串,按照配送顺序依次表示食品车配送的食品的类型。每个字符是以下三个大写字母之一:'M' (表示肉类), 'F' (表示鱼类) 或 'B' (表示面包)。

输出格式 OutputFormat

输出一个整数,表示最大的总产煤量。

样例输入 SampleInput [复制数据]

样例输入1
6
MBMFFB

样例输入2
16
MMBMBBBBMMMMMBMB

样例输出 SampleOutput [复制数据]

样例输出1
12

样例输入2
29

数据范围和注释 Hint

在样例1中,可以按照如下的顺序运送食品车:煤矿 1, 煤矿 1, 煤矿 2, 煤矿 2, 煤矿 1, 煤矿 2, 依次产生的产煤量为1, 2, 1, 2, 3 和 3 个单位,一共是12 个单位。还有其它运送方式也能产生上述最大总和的产煤量。

时间限制 TimeLimitation

前10点时限1s,分值8分
后2点时限3s,分值10分

这题看着就是不可解的。

但是仔细观察会发现它的情况较少,分支巨多(2^N)??

于是我们用滚动数组+Dp显然可以用F[i][j][k][l][m]表示子结构

j,k,l,m为2个矿工最近2次的伙食(0表示没有)

任何坑爹的题目先想想能不能Dp……

记忆化搜索不能滚动还会爆栈,于是Dp的存在性证毕。


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<cctype>
#include<iostream>
#include<functional>
#include<algorithm>
using namespace std;
#define MAXN (100000+10)
#define NDEBUG
int n,a[MAXN];
int f[2][4][4][4][4]; //1->M 2->F 3->B
int cost[4][4][4]={0};
int _cost(int i,int j,int k)
{
	if (k==0) return 0;
	if (i==0) i=k;
	if (j==0) j=k;
	if (i!=j&&i!=k&&j!=k) return 3;
	if (i!=j||i!=k||j!=k) return 2;
	return 1;
}
int main()
{
	#ifndef NDEBUG
	freopen("Vijos1386.in","r",stdin);
	#endif
	scanf("%d",&n);getchar();
	for (int i=0;i<n;i++)
	{
		switch (getchar())
		{
		case 'M':a[i]=1;break;
		case 'F':a[i]=2;break;
		case 'B':a[i]=3;break;
		}
	}
	for (int i=0;i<=3;i++)
		for (int j=0;j<=3;j++)
			for (int k=0;k<=3;k++)
			{
				cost[i][j][k]=_cost(i,j,k);
				#ifndef NDEBUG
				cout<<i<<' '<<j<<' '<<k<<':'<<cost[i][j][k]<<endl;
				#endif
			}


	memset(f,128,sizeof(f));
	f[0][0][0][0][0]=0;
	for (int ii=0;ii<n;ii++)
	{
		int i=ii%2;
		for (int j=0;j<=3;j++)
			for (int k=0;k<=3;k++)
				for (int l=0;l<=3;l++)
					for (int m=0;m<=3;m++)
					{
						if (f[i][j][k][l][m]>=0)
						{
							f[i^1][k][a[ii]][l][m]=max(f[i^1][k][a[ii]][l][m],f[i][j][k][l][m]+cost[j][k][a[ii]]);
							f[i^1][j][k][m][a[ii]]=max(f[i^1][j][k][m][a[ii]],f[i][j][k][l][m]+cost[l][m][a[ii]]);
						}
					}
	}
	int ii=n%2,ans=0;
	for (int j=0;j<=3;j++)
		for (int k=0;k<=3;k++)
			for (int l=0;l<=3;l++)
				for (int m=0;m<=3;m++)
					ans=max(ans,f[ii][j][k][l][m]);
	cout<<ans<<endl;


	return 0;
}


Tyvj P2065(区间嵌套与统计)

P2065 - 「Poetize10」封印一击

From lydliyudong    Normal (OI)
总时限:10s    内存限制:128MB    代码长度限制:64KB

背景 Background

“圣主applepi于公元2011年9月创造了Nescafe,它在散发了16次光辉之后与公元2011年11月12日被封印为一颗魂珠,贮藏于Nescafe神塔之中。公元2012年9月,圣主带领四大护法重启了Nescafe,如今已经是Nescafe之魂的第30次传播了。不久,它就要被第二次封印,而变成一座神杯……”applepi思索着Nescafe的历史,准备着第二次封印。

描述 Description

Nescafe由n种元素组成(编号为1~n),第i种元素有一个封印区间[ai,bi]。当封印力度E小于ai时,该元素将获得ai的封印能量;当封印力度E在ai到bi之间时,该元素将获得E的封印能量;而当封印力度E大于bi时,该元素将被破坏从而不能获得任何封印能量。现在圣主applepi想选择恰当的E,使得封印获得的总能量尽可能高。为了封印的最后一击尽量完美,就请你写个程序帮他计算一下吧!

输入格式 InputFormat

第一行一个整数N。
接下来N行每行两个整数ai、bi,第i+1行表示第i种元素的封印区间。

输出格式 OutputFormat

两个用空格隔开的整数,第一个数是能够获得最多总能量的封印力度E,第二个数是获得的总能量大小。当存在多个E能够获得最多总能量时,输出最小的E。

样例输入 SampleInput [复制数据]

2
5 10
20 25

样例输出 SampleOutput [复制数据]

10 30

数据范围和注释 Hint

对于 50% 的数据,1<=N<=1000,1<=ai<=bi<=10000。 
对于 100% 的数据,1<=N<=10^5,1<=ai<=bi<=10^9。

时间限制 TimeLimitation

各个测试点1s

区间选取

用Past和In_s维护经过的左右结点,

并由此算出

嵌套数(左-右)

左边的区间数=右

右边的区间数=总-(左-右)-右=总-左

PS:由于是闭区间,需要把-右的时间后延


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cctype>
#include<iostream>
#include<functional>
#include<algorithm>
using namespace std;
#define MAXN (200000+10)
#define MAXAi (1000000000)
#define NDEBUG
struct segment_node
{
	int l,type;
	friend bool operator<(const segment_node a,const segment_node b){return (a.l!=b.l)?a.l<b.l:a.type<b.type;	}
	friend bool operator==(const segment_node a,const segment_node b){return (a.l==b.l&&a.type==b.type);	}
	friend bool operator!=(const segment_node a,const segment_node b){return (!(a==b));	}

}a[MAXN];
int n;
long long next[MAXN];
int main()
{
	#ifndef NDEBUG
	freopen("segmentbet.in","r",stdin);
	#endif
	memset(a,0,sizeof(a));
	scanf("%d",&n);n<<=1;
	for (int i=1;i<=n;i+=2)
	{
		scanf("%d%d",&a[i].l,&a[i+1].l);
		a[i].type=-1;a[i+1].type=1;
	}
	sort(a+1,a+n+1);
	int in_s=0,minE=0;
	long long ans=0;
	memset(next,0,sizeof(next));
	for (int i=n-1;i>=1;i--)
	{
		next[i]=next[i+1];
		if (a[i+1].type==-1)
			next[i]+=a[i+1].l;
	}
	int j=1,past=0,pastE=0;
	for (int i=1;i<=n;i++)
	{
		if (a[i]!=a[i+1])
		{
			int len=i-j+1;
			j=i+1;
			len*=-a[i].type;
			if (pastE!=a[i].l) {in_s+=past;past=0;}
			if (len>0) in_s+=len;
			else past+=len;

			long long cost=(long long)(long long)in_s*(long long)a[i].l+next[i];
			if (ans<cost)
			{
				ans=cost;
				minE=a[i].l;
			}

		}

	}
	cout<<minE<<' '<<ans<<endl;
	return 0;
}



Tyvj P2067(质因数分解)

P2067 - [NOIP2012P1]质因数分解

From luchangzhou    Normal (OI)
总时限:10s    内存限制:128MB    代码长度限制:64KB

背景 Background

NOIP2012

描述 Description

已知正整数n 是两个不同的质数的乘积,试求出较大的那个质数。

输入格式 InputFormat

 输入只有一行,包含一个正整数n 。

输出格式 OutputFormat

 输出只有一行,包含一个正整数p ,即较大的那个质数。 

样例输入 SampleInput [复制数据]

21

样例输出 SampleOutput [复制数据]

7

数据范围和注释 Hint

【数据范围】 
对于 60% 的数据 6 ≤ n ≤ 1000
对于 100%的数据 6 ≤ n ≤ 2*10^9

来源 Source

NOIP2012

O(√n)
注意要枚举1-√n而不是√n-n,数量级差很多。


#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<cctype>
#include<iostream>
#include<functional>
#include<algorithm>
using namespace std;
#define MAXN (100000+10)
#define MAXAi (1000000000+10)
int n;
int main()
{
	cin>>n;
	for (int i=2;i<=n;i++)
		if (!(n%i))
		{
			cout<<n/i<<endl;return 0;
		}


}

CF 242E(zkw线段树-拆位)

E. XOR on Segment
time limit per test

4 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

对于数组,a1, a2, ..., an.
请维护2个操作。

  1. 区间[l, r], 求和.
  2. 将区间 [l, r],上的数异或x
Input

第一行为数组大小 n (1 ≤ n ≤ 105), 第二行为数组 a1, a2, ..., an(0 ≤ ai ≤ 106

第三行为操作数 m (1 ≤ m ≤ 5·104),接下来每行第1个数ti (1 ≤ ti ≤ 2)
表示进行第i种操作. ‘1
li, ri
 ‘(1 ≤ li ≤ ri ≤ n)表示[l,r]求和.‘2 li, ri, xi (1 ≤ li ≤ ri ≤ n, 1 ≤ xi ≤ 106)表示将区间 [l, r],上的数异或x

Output

输出所有操作1的结果。

不要用%lld 占位符,改用输入输出流或%I64占位符.

Sample test(s)
input
5
4 10 3 13 7
8
1 2 4
2 1 3 3
1 2 4
1 3 3
2 2 5 5
1 1 5
2 1 2 10
1 2 3
output
26
22
0
34
11
input
6
4 7 4 0 7 3
5
2 2 3 8
1 1 5
2 3 5 1
2 4 5 6
1 2 3
output
38
28

这题是xor拆位法的运用

显然我们可以用t[i,j]表示第i位上的1的个数,之后求和统计(这是xor操作优化的常用手段)

zkw线段树加Lazy标记时,用tot[]表示区间上的总数(其实也可以时事算出来)


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<cctype>
#include<iostream>
using namespace std;
#define MAXN (100000+10)
#define MAXAi (1000000+10)
#define LogMAXAi (20)
#define MAXm (50000)
#define NDEBUG
int n,m,M,t[LogMAXAi+10][MAXN*10],tot[MAXN*10]={0};
bool b[LogMAXAi+10][MAXN*10]={0};
void build_tree()
{
	for (int i=M+1;i<=M+n;i++) tot[i]=1;
	for (int i=M-1;i>=1;i--) tot[i]=tot[i<<1]+tot[(i<<1)^1];

}
long long count_a_tree_node(int x)
{
	long long ans=0;
	for (int i=0,p=1;i<20;i++,p<<=1) ans+=(long long)(p)*(long long)(t[i][x]);
	return ans;
}
long long quere(int l,int r)
{
	long long ans=0;
	l--;r++;
	l+=M;r+=M;
	while (l^r^1)
	{
		if (~l&1) ans+=count_a_tree_node(l+1);
		if (r&1) ans+=count_a_tree_node(r-1);
		l>>=1;r>>=1;
	}
	return ans;
}
void pushdown(int x)
{
	if (x!=1) pushdown(x>>1);
	for (int i=0;i<20;i++)
	{
		if (b[i][x])
		{
			t[i][x<<1]=tot[x<<1]-t[i][x<<1];
			t[i][(x<<1)^1]=tot[(x<<1)^1]-t[i][(x<<1)^1];
			b[i][x]=0;b[i][x<<1]^=1;b[i][(x<<1)^1]^=1;
		}
	}
}
void update(int x)
{
	for (int i=0;i<20;i++)
	{
		int xx=x;
		for (x>>=1;x;x>>=1)
			t[i][x]=t[i][x<<1]+t[i][(x<<1)^1];
		x=xx;
	}
}
void a_t_xor(int j,int l,int r)
{
	l--;r++;
	l+=M;r+=M;
	while (l^r^1)
	{
		if (~l&1) {t[j][l+1]=tot[l+1]-t[j][l+1];b[j][l+1]^=1;	}
		if (r&1) {t[j][r-1]=tot[r-1]-t[j][r-1];b[j][r-1]^=1;	}
		l>>=1;r>>=1;
	}
}
void t_xor(int l,int r,int x)
{
	for (int i=0;x;i++,x>>=1) {if (x&1) a_t_xor(i,l,r);	}
}
int main()
{
//	freopen("CF_242E.in","r",stdin);
	memset(t,0,sizeof(t));
	scanf("%d",&n);
	M=1;while (M-2<n) M<<=1; //cout<<M<<endl;
	for (int i=M+1;i<=M+n;i++)
	{
		scanf("%d",&t[0][i]);
		int j=0;
		while (t[j][i]) {t[j+1][i]=t[j][i]/2;t[j][i]&=1;j++;}
	}
	for (int j=0;j<=19;j++)
	{
		for (int i=M-1;i>=1;i--) t[j][i]=t[j][i<<1]+t[j][(i<<1)^1];
	}
	#ifndef NDEBUG
	for (int i=1;i<=M+n;i++)
	{
		for (int j=0;j<=19;j++) cout<<t[j][i]<<' ';
		cout<<endl;
	}
	#endif
	build_tree();
	/*
	for (int i=1;i<=M+n;i++) cout<<tot[i]<<' ';
	cout<<endl;
	*/
	scanf("%d",&m);
	while (m)
	{
		int p;
		scanf("%d",&p);
		if (p==1)
		{
			int l,r;scanf("%d%d",&l,&r);
			pushdown(l-1+M);pushdown(r+1+M);
			cout<<quere(l,r)<<endl;
		}
		else
		{
			int l,r,x;
			scanf("%d%d%d",&l,&r,&x);
			pushdown(l-1+M);pushdown(r+1+M);
			t_xor(l,r,x);
			update(l-1+M);update(r+1+M);
		}

		#ifndef	NDEBUG
		for (int i=1;i<=M+n;i++)
		{
			for (int j=0;j<=19;j++) cout<<t[j][i]<<' ';
			cout<<endl;
		}
		#endif
		m--;
	}
	return 0;
}

RQNOJ 60(zkw线段树-xor区间与区间求和)

查看题目 Show Problem

题目:美丽的中国结

问题编号:60


题目描述

题目背景
kitty刚刚高三毕业.看到同学们都回家的回家,旅游的旅游,她的心里有些落寞.英俊潇洒风流倜傥迷倒万千KL却仅对kitty感冒的fish看在眼里,急在心里.一天,fish提出和kitty两个人一起外出旅游.kitty犹豫了几天,想好能瞒过家长的理由后(要问是什么……自己猜去),答应了.fish很高兴地带着kitty去登记了(别想歪,登记旅游团而已……),日照青岛五日游.
当然啦,他们玩得很高兴.虽然这次旅行是fish先提议的,但kitty因为玩得很畅快(刚高考完嘛),所以想送给fish一份礼物,一份能让见多识广的fish都无法忘怀的礼物.她从路边 9¾站台的某算命先生那里得知中国结具有增加RP的效果,而这正是fish所需要的,因此她决定动手给fish编一个奇特的中国结.

题目描述
中国结形式多样,fish会喜欢什么样的呢?思考几天后,kitty决定给fish编一个树状的中国结.这个中国结有n个结点(编号1,2,…,n),这n个结点之间总共恰有n-1条线相连,其中结点1上是树的根.这是一个奇特的中国结,因此它的编织方式也很奇特.在编织过程中的每一步骤,kitty有时需要将一个结点子树里的所有结点i的状态全部取反(如果原来结点i已经打结,则解开i,否则将结点i打结),有时又需要知道一个结点的子树里有多少已经打结的结点,你能帮助可爱的kitty完成这份礼物吗?

数据规模
对于40% 的数据,1≤n≤10000, 1≤m≤20000
对于100%的数据,1≤n≤100000, 1≤m≤100000

输入格式

输入
第一行有个整数n,表示这个中国结有n个结点
以下n-1行,每行有两个整数u和v(1≤u,v≤n),表示结点u和v间有一条线相连;
再一行有个整数m,表示kitty要进行的步骤数
以下m行,每行可能为:
"C x":表示将结点x的子树中所有结点的状态取反(包括x)

"Q x":表示kitty想知道结点x的子树中有多少已经打结的结点(包括x)

输出格式

对于每个“Q x”输出一行整数,表示结点x的子树中有多少已经打结的结点(包括x)

样例输入

5
1 2
1 3
2 4
2 5
5
Q 1
C 1
Q 1
C 2
Q 1

样例输出

0
5
2

zkw线段树在某个区间上取反(xor 1) ,求某个区间的和

zkw线段树的标记永久化在该题中不适用、

所以可以记一般的Lazy标记--

在处理区间时,把这个区间可能用到的点的标记全部下传

处理完区间后update左、右结点,把区间上传(这样就能消除标记上方结点为0对结果的影响)

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<cctype>
#include<functional>
#include<algorithm>
using namespace std;
#define MAXN (100000+10)
#define MAXm (100000+10)
#define NDEBUG
int n,m,M,t[MAXN*10]={0},l[MAXN],r[MAXN];
bool mark[MAXN*10]={false};
char s[50];
int head[MAXN*2]={0},next[MAXN*2],edge[MAXN*2],size=0;
void addedge(int u,int v)
{
	edge[++size]=v;
	next[size]=head[u];
	head[u]=size;
}
int tim=0;
bool b[MAXN]={0};
void dfs(int u)
{
	b[u]=1;l[u]=++tim;
	int p=head[u];
	while (p)
	{
		if (!b[edge[p]]) dfs(edge[p]);
		p=next[p];
	}
	r[u]=++tim;
}
void pushdown(int x,int p)
{
	if (!x) return;
	pushdown(x>>1,p<<1);
	if (mark[x>>1])
	{
		mark[x]^=1;mark[x^1]^=1;mark[x>>1]=0;
		t[x]=p-t[x];t[x^1]=p-t[x^1];
	}
	x>>=1;

}
void update(int x)
{
	for (x>>=1;x;x>>=1) t[x]=t[x<<1]+t[(x<<1)^1];
}
int main()
{
	#ifndef NDEBUG
	freopen("RQNOJ60.in","r",stdin);
	#endif
	scanf("%d",&n);
	for (int i=1;i<n;i++) {int u,v;scanf("%d%d",&u,&v);addedge(u,v);addedge(v,u);	}
	dfs(1);
	M=1;while (M-2<r[1]+1) M<<=1;
	scanf("%d",&m);
	#ifndef NDEBUG
//	cout<<M;
	for (int i=1;i<=n;i++) cout<<i<<':'<<l[i]<<'-'<<r[i]<<' ';
	cout<<'n';
	#endif
	for (int k=1;k<=m;k++)
	{
		int x;
		scanf("%s%d",s,&x);
		if (s[0]=='Q')
		{
			int ans=0,p1=l[x],p2=r[x];
			p1--;p2++;p1+=M;p2+=M;
			pushdown(p1,1);pushdown(p2,1);
//			cout<<"add: ";
			#ifndef NDEBUG
			cout<<p1<<' '<<p2<<endl;
			#endif
//			cout<<mark[10];
			while (p1^p2^1)
			{
				if (~p1&1) {/*pushdown(p1+1,1);*/ans+=t[p1+1];/*cout<<p1+1<<':'<<t[p1+1]<<' ';*/}
				if (p2&1)  {/*pushdown(p2-1,1);*/ans+=t[p2-1];/*cout<<p2-1<<':'<<t[p2-1]<<' ';*/}
				p1>>=1;p2>>=1;
			}
			cout<<ans/2<<endl;
		}
		else
		{
			int p=1,p1=l[x],p2=r[x];
			p1--;p2++;p1+=M;p2+=M;
			pushdown(p1,1);pushdown(p2,1);
			while (p1^p2^1)
			{
				if (~p1&1) {mark[p1+1]^=1;t[p1+1]=p-t[p1+1];/*cout<<p1+1<<' ';*/}
				if (p2&1) {mark[p2-1]^=1;t[p2-1]=p-t[p2-1];/*cout<<p2-1<<' ';*/}
				p1>>=1;p2>>=1;p<<=1;
			}
/*			for (int i=1;i<=M*2;i++) if (mark[i]) cout<<i<<':'<<t[i]<<' ';
			cout<<endl;*/
//			update(p1);

			update(l[x]-1+M);
/*			for (int i=1;i<=M*2;i++) if (mark[i]) cout<<i<<':'<<t[i]<<' ';
			cout<<endl;
*/			update(r[x]+1+M);

		}
		#ifndef NDEBUG
		for (int i=1;i<=n;i++) if (mark[i]) cout<<i<<' ';
		cout<<endl;
		#endif

	}



	return 0;
} 

HDU 4302(zkw线段树-单点修改区间最值)

Holedox Eating

Problem Description
Holedox在一条长度为L的线上. Holedox能在线上移动,线上会时不时的出现蛋糕(保证是整点)。Holedox会在想吃蛋糕时去最近的有蛋糕的点吃,如果左右的最近蛋糕与它的距离相等,它会按上一次行走的方向,如果没有蛋糕,它会呆在原地。
 


Input
第一行为数据组数T (1 <= T <= 10)
对每组数据,第一行有2个整数L,n(1<=L,n<=100000)表示线段长度和事件数。
接下来n行,每行一个事件:‘0 x'表示在x的位置出现一块蛋糕,’1‘表示Holedox去吃1块蛋糕
Holedox一开始在0点。
 


Output
对每组数据,输出一行‘Case i: dis',dis表示Holedox的移动距离。
 


Sample Input
3 10 8 0 1 0 5 1 0 2 0 0 1 1 1 10 7 0 1 0 5 1 0 2 0 0 1 1 10 8 0 1 0 1 0 5 1 0 2 0 0 1 1
 


Sample Output
Case 1: 9 Case 2: 4 Case 3: 2
 

这题是单点修改+区间最值的zkw线段树(a[]表示数量)

这题有几个技巧:

1.线段树多开;

2.'0'点的包含(把所有数字+1,显然不影响Holedox的移动距离)

3.额外信息的记录(为了把这题转换成线段树)


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<cctype>
#include<iostream>
using namespace std;
#define MAXT (10+10)
#define MAXN (100000+10)
#define MAXm (100000+10)
#define INF (2139062143)
int n,m,M,T,now,direction,ans;
int t[2][MAXN*10];  //0->max 1->min
int a[MAXN];
void dec(int x)
{
	a[x]--;
	if (a[x]==0)
	{
		x+=M;
		t[0][x]=0;t[1][x]=INF;
		for (x>>=1;x;x>>=1)
		{
			t[0][x]=max(t[0][x<<1],t[0][(x<<1)^1]);
			t[1][x]=min(t[1][x<<1],t[1][(x<<1)^1]);
		}
	}
}
void go_left(int Lans)
{
	ans+=now-Lans;
	now=Lans;direction=-1;
	dec(now);
}
void go_right(int Rans)
{
	ans+=Rans-now;
	now=Rans;direction=1;
	dec(now);
}
int main()
{
	freopen("Holding.in","r",stdin);
	scanf("%d",&T);
	for (int k=1;k<=T;k++)
	{
		memset(t[0],0,sizeof(t[0]));ans=0;
		memset(t[1],127,sizeof(t[1]));
		memset(a,0,sizeof(a));now=1;direction=1; //1->right -1->left
		scanf("%d%d",&n,&m);n+=2;
		M=1;while (M-2<n) M<<=1;
		for (int i=1;i<=m;i++)
		{
			int p1,p2;
			scanf("%d",&p1);
			if (p1==0)
			{
				scanf("%d",&p2);p2+=1;
				a[p2]++;
				if (a[p2]==1)
				{
					p2+=M;t[0][p2]=t[1][p2]=p2-M;
					int p=p2;
					for (p>>=1;p;p>>=1) t[0][p]=max(t[0][p<<1],t[0][(p<<1)^1]);
					for (p2>>=1;p2;p2>>=1) t[1][p2]=min(t[1][p2<<1],t[1][(p2<<1)^1]);
				}
			}
			else
			{
				//(0,now+1)->[1,now]
				int l=M,r=now+1+M,Lans=0,Rans=INF;
				while (l^r^1)
				{
					if (~l&1) Lans=max(Lans,t[0][l+1]);
					if (r&1) Lans=max(Lans,t[0][r-1]);
					l>>=1;r>>=1;
				}
				//(now-1,n)->[now,n-1]
				l=now-1+M;r=n+M;
				while (l^r^1)
				{
					if (~l&1) Rans=min(Rans,t[1][l+1]);
					if (r&1) Rans=min(Rans,t[1][r-1]);
					l>>=1;r>>=1;
				}
				if (Lans==0&&Rans==INF) continue;
				else if (Lans==0) go_right(Rans);
				else if (Rans==INF) go_left(Lans);
				else if (now-Lans<Rans-now) go_left(Lans);
				else if (now-Lans>Rans-now) go_right(Rans);
				else if (now-Lans==0) dec(now);
				else if (direction==1) go_right(Rans);
				else go_left(Lans);




			}
			/*
				for (int j=1;j<=M*2;j++) if (t[0][j]) cout<<j<<":"<<t[0][j]<<' ';
				cout<<endl;
				for (int j=1;j<=M*2;j++) if (t[1][j]<INF) cout<<j<<":"<<t[1][j]<<' ';
				cout<<endl;
			*/




		}
		printf("Case %d: %dn",k,ans);

	}
	return 0;
}

POJ 2155(二维zkw线段树)

Language:
Matrix
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 13137   Accepted: 4948

Description

给定一个矩阵(初始为0),维护2个操作:
1. C x1 y1 x2 y2 (1 <= x1 <= x2 <= n, 1 <= y1 <= y2 <= n) ,以(x1,y1)为左上角,(x2,y2)为右上角的矩阵取反。
2. Q x y (1 <= x, y <= n) 输出(x,y)的状态

Input

第一行为数据组数X (X <= 10)
每组数据第一行为N,T (2 <= N <= 1000, 1 <= T <= 50000) 表示矩阵边长与操作次数。
接下来T行,为Q或C操作 

Output

请输出所有提问结果。
每组数据后一回车。 

Sample Input

1
2 10
C 2 1 2 2
Q 2 2
C 2 1 2 1
Q 1 1
C 1 1 2 1
C 1 2 1 2
C 1 1 2 2
Q 1 1
C 1 1 2 1
Q 2 1

Sample Output

1
0
0
1

Source

POJ Monthly,Lou Tiancheng

这题是二维的线段树,

先建一棵线段树,再将它的所有结点(包括根)建立一个二叉树(维护这个结点)

异或仅需记录标记某点所对应的区间取反

查找时统计共记了几个标记即可(标记永久化)


Program Matrix;
const
   maxtt=10;
   maxn=1000;
   maxMM=50000;
var
   tt,n,mm,i,j,k,x1,y1,x2,y2,x,y,p1,p2,ans:longint;
   c:char;
   t:array[1..5000,1..5000] of boolean;
   M:longint;

Procedure change_y(x,y1,y2:longint);
var
   i,j:longint;
begin
   dec(y1);inc(y2);
   inc(y1,M);inc(y2,M);
   while ((y1 xor y2 xor 1)>0) do
   begin
      if ((y1 and 1)=0) then t[x,y1+1]:=not(t[x,y1+1]);
      if ((y2 and 1)=1) then t[x,y2-1]:=not(t[x,y2-1]);
      y1:=y1 shr 1;y2:=y2 shr 1;
   end;

end;

Procedure change_x(x1,y1,x2,y2:longint);
var
   i,j:longint;
begin
   dec(x1);inc(x2);
   inc(x1,M);inc(x2,M);
   while ((x1 xor x2 xor 1)>0) do
   begin
      if ((x1 and 1)=0) then change_y(x1+1,y1,y2);
      if ((x2 and 1)=1) then change_y(x2-1,y1,y2);
      x1:=x1 shr 1;x2:=x2 shr 1;
   end;
end;

function find_y(x,y:longint):boolean;
var
   i,j:longint;
begin
   inc(y,M); find_y:=false;
   while (y>0) do
   begin
      if (t[x,y]) then find_y:=not(find_y);
      y:=y shr 1;
   end;

end;
function find_x(x,y:longint):boolean;
var
   i,j:longint;
begin
   inc(x,M); find_x:=false;
   while (x>0) do
   begin
      find_x:=find_x xor find_y(x,y);
      x:=x shr 1;
   end;
end;
begin
   readln(tt);
   while (tt>0) do
   begin
      fillchar(t,sizeof(t),false);
      readln(n,mm);
      M:=1;
      while (M-2<n) do M:=M shl 1;
      for k:=1 to mm do
      begin
         read(c);
         if c='C' then
         begin
            readln(x1,y1,x2,y2);
            change_x(x1,y1,x2,y2);





         end
         else
         begin     //Q
            readln(x1,y1);
            if (find_x(x1,y1)) then writeln('1') else writeln('0');


         end;



      end;
      dec(tt);
      if (tt>0) then writeln;
   end;
end.