题目描述
在太平洋中心有一个圆形小岛,沿着小岛的海岸线分布着n个小镇,编号分别为1,2,3~~n;小镇i-1、小镇i、小镇i+1是相邻的(当然小镇n与小镇1相邻)。相邻小镇之间存在一条公路,公路也有编号,公路i连接小镇i和小镇i+1,公路n连接小镇n和小镇1.现在对小岛有m个操作,操作有两种:
询问操作:1 x y 代表小镇x到小镇y是否联通,联通输出1,否则输出0
修改操作:0 x 代表修改公路x,如果公路原来是完好的,则断开,否则修好公路x。
输入格式:
输入第一行为一个整数t,代表下来有t组数据
每组数据输入第一行包含两个整数n,m,分别表示小镇个数和操作命令数目。
输入接下来的m行,每一行代表一条操作指令。
输出格式:
对于相邻两组数据之间要留一空行。
输入样例:
1
5 10
1 2 5
0 4
1 4 5
0 2
1 3 4
1 1 3
0 1
0 2
1 2 4
1 2 5
输出样例:
1
1
1
0
1
0
数据规模:
对于20%的数据满足:1 < = n, m <=1000。
对于40%的数据满足:1 < = n, m <= 100000。
对于100%的数据满足:1 < = n, m <= 500000。
解题思路:这道题目是树状数组的一个小变形。其实与树状数组原版也不没有太大的区别。
代码:(请不要直接拷贝哦)
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,m,c[500005];
bool vis[500005];
inline int lowbit(int x)//标配
{
return x&-x;
}
inline void add(int x,int y)//标配
{
while(x<=n)
{
c[x]=c[x]+y;
x+=lowbit(x);
}
}
inline int sum(int x)//标配
{
int s=0;
while(x>0)
{
s+=c[x];
x-=lowbit(x);
}
return s;
}
int main()
{
int s,t;
int x,y,ss;
scanf("%d",&t);
while(t--)//输入多组数据
{
memset(c,0,sizeof(c));//初始化
memset(vis,0,sizeof(vis));
scanf("%d%d",&n,&m);
for (int i=0;i<m;i++)
{
scanf("%d",&s);
if (s==1)//查询
{
scanf("%d%d",&x,&y);
if (x>y)
{//交换
int tt;
tt=x;
x=y;
y=tt;
}
if (sum(y-1)-sum(x-1)==0)
printf("1\n"); else
if ((sum(x-1)==0)&&(sum(n-1)-sum(y-1)==0)&&(vis[n]==0))
printf("1\n"); else
printf("0\n");
}
else
{
scanf("%d",&x);
if (vis[x]==1)//这条路是否连上的
{
ss=-1;
vis[x]=0;
}
else
{
ss=1;
vis[x]=1;
}
add(x,ss);//改变
}
}
printf("\n");//两个数据间要有空行
}
return 0;
}