大家好,我是一个连分块都不会不想打的蒟蒻,于是我就用b i t s e t bitsetbitset水过了这题
另外,小蒟蒻其实不是很熟悉b i t s e t bitsetbitset,如果写得不优,还请大佬轻D
en…让我们理性分析一下时间复杂度:O ( n m w ) O(\frac{nm}{w})O(wnm),w ww为64,那也到了接近8 e 8 8e88e8的复杂度…可以说是相当硬核的A C ACAC了.
本题的题意相当清晰,只需要提供2 22种操作:
1 11.区间异或
2 22.求某一位上的值
很明显都是可以用b i t s e t bitsetbitset来做的,这里讲讲b i t s e t bitsetbitset的基本操作(也可以去看洛谷日报:
头文件
都9102年了还不用万能库?
#include<bitset>
定义
std::bitset<位数>bit;
初始化
bit.set();//全部变成1
bit.reset();//全部变成0
位运算
和正常位运算一样
求某1位的值
和数组一致
然后回到这题,对于区间异或,我们可以先全部赋值为1,然后先右移使b i t s e t bitsetbitset中正好有r − l + 1 r-l+1r−l+1个1,再将它左移(l-1)位(b i t s e t bitsetbitset也是从0开始),与原来的b i t s e t bitsetbitset进行异或操作就行了
询问?直接输出s [ i − 1 ] s[i-1]s[i−1](从0 00
开始)
然后这题就愉快地水过啦!
另外自带大常数的同学们,O 3 O_3O3和O f a s t OfastOfast可以在O 2 O_2O2的基础上再减小50%的常数哦(逃
代码:
// luogu-judger-enable-o2
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define getchar() (p1==p2 and (p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<23],*p1=buf,*p2=buf;
//fread快读优化模板拿走不谢
inline void read(int &a){
a=0;
char c=getchar();
while(c>57 or c<48)c=getchar();
while(47<c and c<58){
a=a*10+c-48;
c=getchar();
}
}
int n,m,opt,l,r;
std::bitset<100000>bit,ha;//bit为原来的bitset
//乱取的变量名是因为真的想不到能AC(逃)
int main(){
read(n);read(m);
for(int i=1;i<=m;++i){
read(opt);
if(opt&1){
read(l);read(r);
int lon=r-l+1;
int p=100000-lon;
ha.set();
ha>>=p;
//右移至只剩r-l+1个1
ha<<=(l-1);//移到l-r的位置
bit^=ha;
}
else{
read(l);
puts(bit[l-1]?"1":"0");
//bitset用print会警告,不过也无所谓
}
}
return 0;
}
版权声明:本文为qq_38253946原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。