您的位置:首页 > 其它

【bzoj1858】【Scoi2010】序列操作【位运算】【卡常大法好】

2015-03-10 21:08 344 查看
其实这道题用线段树神马的应该是可做的……

但是鉴于我跪烂的位运算水平……

我决定用位运算压常数水过去~~

(其实要是数据强的话我早就完了)

我一次又一次犯的,b错误耗费了我一下午的时间……

这就是蒟蒻啊- -

一开始不知怎么回事,命令总是读不进去- -

然后发现~0U<<(r+1)有的时候不总是好用。

printf("%u\n",~0U<<32);
int r=32;
printf("%u\n",~0U<<r);


这两条语句的输出结果一个是0,一个是4294967295……

所以为了避免这种悲催的情况,就把~0U<<<<(r+1)改成~0U<<<
呵呵。

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef unsigned int uint;
struct bitset{
static const int maxlen=(100000>>5)+1;
static const uint inf=~0U;
uint d[maxlen];
int list[65536];
inline int cnt(uint x){
return list[x&0xFFFF]+list[x>>16];
}
void Not(int l,int r){
int l1=l>>5,r1=r>>5;
l&=31;r&=31;
d[l1]^=(1<<l)-1;
d[r1]^=inf<<r<<1;
for(;l1<=r1;++l1) d[l1]^=inf;
}
inline int count(int l,int r){
int ans=0;
int l1=l>>5,r1=r>>5;
l&=31,r&=31;
ans-=cnt(d[l1]&((1<<l)-1));
ans-=cnt(d[r1]>>r>>1);
for(;l1<=r1;++l1) ans+=cnt(d[l1]);
return ans;
}
void clear(int l,int r){
int l1=l>>5,r1=r>>5;
l&=31,r&=31;
if(l1==r1){d[l1]&=~((uint)(((1LL<<(r-l+1))-1)<<l));return;}
d[l1]&=(1<<l)-1;
d[r1]&=inf<<r<<1;
for(++l1;l1<r1;++l1) d[l1]=0;

}
void set(int l,int r){
int l1=l>>5,r1=r>>5;
l&=31,r&=31;
if(l1==r1){d[l1]|=(uint)(((1LL<<(r-l+1))-1)<<l);return;}
d[l1]|=inf<<l;
d[r1]|=(uint)((1LL<<r<<1)-1);
for(++l1;l1<r1;++l1) d[l1]=inf;
}
inline uint get(int pos){return (d[pos>>5]>>(pos&31))&1;}
}a;
inline int read(){
int x=0;
char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) x=x*10+ch-48,ch=getchar();
return x;
}
int s[10];
void print(int x){
if(x) s[0]=0;
else s[0]=1,s[1]=0;
while(x) s[++s[0]]=x%10,x/=10;
while(s[0]) putchar(48+s[s[0]--]);
putchar('\n');
}
int main(){
for(int i=0;i<65536;++i) a.list[i]=a.list[i>>1]+(i&1);
int n=read(),m=read();
for(int i=0;i<n;++i)
a.d[i>>5]|=(read()<<(i&31));//i&31!!!!
while(m--){
int opt=read(),x=read(),y=read();
int ans,tmp;
switch(opt){
case 0:a.clear(x,y);break;
case 1:a.set(x,y);break;
case 2:a.Not(x,y);break;
case 3:print(a.count(x,y));break;
case 4:
ans=0;tmp=0;
for(int i=x;i<=y;++i){
if(a.get(i))tmp++;
else ans=max(ans,tmp),tmp=0;
}
print(max(ans,tmp));
break;
}
//      a.print();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: