hdu 3397 线段树
2015-04-22 22:03
405 查看
题意: Change operations:
0 a b change all characters into '0's in [a , b]
1 a b change all characters into '1's in [a , b]
2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
Output operations:
3 a b output the number of '1's in [a, b]
4 a b output the length of the longest continuous '1' string in [a , b]
Sample Input
1
10 10
0 0 0 1 1 0 1 0 1 1
1 0 2
3 0 5
2 2 2
4 0 4
0 3 6
2 3 7
4 2 8
1 0 5
0 5 6
3 3 9
Sample Output
5
2
6
5
嗯嗯
2015-07-26:专题复习
View Code
0 a b change all characters into '0's in [a , b]
1 a b change all characters into '1's in [a , b]
2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
Output operations:
3 a b output the number of '1's in [a, b]
4 a b output the length of the longest continuous '1' string in [a , b]
Sample Input
1
10 10
0 0 0 1 1 0 1 0 1 1
1 0 2
3 0 5
2 2 2
4 0 4
0 3 6
2 3 7
4 2 8
1 0 5
0 5 6
3 3 9
Sample Output
5
2
6
5
嗯嗯
2015-07-26:专题复习
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<queue> #include<map> using namespace std; #define MOD 1000000007 const int INF=0x3f3f3f3f; const double eps=1e-5; #define cl(a) memset(a,0,sizeof(a)) #define ts printf("*****\n"); #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define root 1,n,1 #define mid ((l+r)>>1) const int MAXN=100010; int n,m,t,Min,tt; int msum1[MAXN<<2],col[MAXN<<2],lsum1[MAXN<<2],rsum1[MAXN<<2]; int msum0[MAXN<<2],lsum0[MAXN<<2],rsum0[MAXN<<2],xxor[MAXN<<2]; int sum1[MAXN<<2],sum0[MAXN<<2]; void fun1(int rt,int m,int val) //改变区间内0/1的变化 { msum1[rt]=lsum1[rt]=rsum1[rt]=sum1[rt]=val?m:0; msum0[rt]=lsum0[rt]=rsum0[rt]=sum0[rt]=val?0:m; } void fun2(int rt) { swap(msum1[rt],msum0[rt]); swap(lsum1[rt],lsum0[rt]); swap(rsum1[rt],rsum0[rt]); swap(sum1[rt],sum0[rt]); } void pushup(int rt,int m) { sum1[rt]=sum1[rt<<1]+sum1[rt<<1|1]; lsum1[rt]=lsum1[rt<<1]; rsum1[rt]=rsum1[rt<<1|1]; if(lsum1[rt]==(m-(m>>1))) lsum1[rt]+=lsum1[rt<<1|1]; if(rsum1[rt]==(m>>1)) rsum1[rt]+=rsum1[rt<<1]; msum1[rt]=max(lsum1[rt<<1|1]+rsum1[rt<<1],max(msum1[rt<<1],msum1[rt<<1|1])); sum0[rt]=sum0[rt<<1]+sum0[rt<<1|1]; lsum0[rt]=lsum0[rt<<1]; rsum0[rt]=rsum0[rt<<1|1]; if(lsum0[rt]==(m-(m>>1))) lsum0[rt]+=lsum0[rt<<1|1]; if(rsum0[rt]==(m>>1)) rsum0[rt]+=rsum0[rt<<1]; msum0[rt]=max(lsum0[rt<<1|1]+rsum0[rt<<1],max(msum0[rt<<1],msum0[rt<<1|1])); } void build(int l,int r,int rt) { col[rt]=-1; xxor[rt]=0; if(l==r) { int num; scanf("%d",&num); msum1[rt]=lsum1[rt]=rsum1[rt]=sum1[rt]=num?1:0; msum0[rt]=lsum0[rt]=rsum0[rt]=sum0[rt]=num?0:1; return; } build(lson); build(rson); pushup(rt,r-l+1); } void pushdown(int rt,int m) { if(col[rt]!=-1) { xxor[rt<<1]=xxor[rt<<1|1]=0; col[rt<<1]=col[rt<<1|1]=col[rt]; fun1(rt<<1,m-(m>>1),col[rt]); fun1(rt<<1|1,m>>1,col[rt]); col[rt]=-1; } else if(xxor[rt]) { if(col[rt<<1]!=-1) { col[rt<<1]^=1; fun1(rt<<1,m-(m>>1),col[rt<<1]); } else { xxor[rt<<1]^=1; fun2(rt<<1); //最大连续1的变化有点麻烦,必须要重新开一个最大连续0的变量 } if(col[rt<<1|1]!=-1) { col[rt<<1|1]^=1; fun1(rt<<1|1,(m>>1),col[rt<<1|1]); } else { xxor[rt<<1|1]^=1; fun2(rt<<1|1); } xxor[rt]=0; } } void update(int L,int R,int val,int l,int r,int rt) { if(l>=L&&r<=R) { if(val<=1) { xxor[rt]=0; col[rt]=val; fun1(rt,r-l+1,val); } else { if(col[rt]!=-1) { col[rt]^=1; fun1(rt,r-l+1,col[rt]); } else { xxor[rt]^=1; fun2(rt); } } return; } pushdown(rt,r-l+1); if(L<=mid) update(L,R,val,lson); if(R>mid) update(L,R,val,rson); pushup(rt,r-l+1); } int query1(int L,int R,int l,int r,int rt) //查询区间内1的个数 { if(l>=L&&r<=R) { return sum1[rt]; } pushdown(rt,r-l+1); int ans=0; if(L<=mid) ans+=query1(L,R,lson); if(R>mid) ans+=query1(L,R,rson); return ans; } int query2(int L,int R,int l,int r,int rt) //查询区间内最长连续1的个数 { if(l>=L&&r<=R) { return msum1[rt]; } pushdown(rt,r-l+1); if(R<=mid) return query2(L,R,lson); if(L>mid) return query2(L,R,rson); int a=query2(L,R,lson); int b=query2(L,R,rson); a=max(a,b); b=min(mid-L+1,rsum1[rt<<1])+min(R-mid,lsum1[rt<<1|1]); return max(a,b); } int main() { #ifndef ONLINE_JUDGE freopen("1.in","r",stdin); #endif int t,n,m,op,a,b; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); build(root); while(m--) { scanf("%d%d%d",&op,&a,&b); a++,b++; if(op<=2) update(a,b,op,root); else { if(op==3) printf("%d\n",query1(a,b,root)); else printf("%d\n",query2(a,b,root)); } } } return 0; }
View Code
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 100010; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int num0[maxn<<2],num1[maxn<<2]; int lb0[maxn<<2],lb1[maxn<<2]; int rb0[maxn<<2],rb1[maxn<<2]; int mx1[maxn<<2],mx0[maxn<<2]; int col[maxn<<2]; int xxor[maxn<<2]; int num; int max(int a,int b){ return a>b?a:b; } int min(int a,int b){ return a<b?a:b; } void pushup(int rt,int m) { lb0[rt]=lb0[rt<<1];rb0[rt]=rb0[rt<<1|1]; if(lb0[rt]==m-(m>>1)) lb0[rt]+=lb0[rt<<1|1]; if(rb0[rt]==(m>>1)) rb0[rt]+=rb0[rt<<1]; lb1[rt]=lb1[rt<<1];rb1[rt]=rb1[rt<<1|1]; if(lb1[rt]==m-(m>>1)) lb1[rt]+=lb1[rt<<1|1]; if(rb1[rt]==(m>>1)) rb1[rt]+=rb1[rt<<1]; num0[rt]=num0[rt<<1]+num0[rt<<1|1]; num1[rt]=num1[rt<<1]+num1[rt<<1|1]; mx1[rt]=max(mx1[rt<<1],mx1[rt<<1|1]); mx1[rt]=max(mx1[rt],rb1[rt<<1]+lb1[rt<<1|1]); mx0[rt]=max(mx0[rt<<1],mx0[rt<<1|1]); mx0[rt]=max(mx0[rt],rb0[rt<<1]+lb0[rt<<1|1]); } void build(int l,int r,int rt){ col[rt]=-1; xxor[rt]=0; if(l==r){ scanf("%d",&num); num0[rt]=lb0[rt]=rb0[rt]=mx0[rt]=(num?0:1); num1[rt]=lb1[rt]=rb1[rt]=mx1[rt]=(num?1:0); return ; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt,r-l+1); } void init(int rt,int m,int cmd){ lb0[rt]=rb0[rt]=mx0[rt]=num0[rt]=m*(1-cmd); lb1[rt]=rb1[rt]=mx1[rt]=num1[rt]=m*cmd; } void change(int rt){ swap(lb0[rt],lb1[rt]); swap(rb0[rt],rb1[rt]); swap(mx0[rt],mx1[rt]); swap(num0[rt],num1[rt]); } void pushdown(int rt,int m){ if(col[rt]!=-1){ col[rt<<1]=col[rt<<1|1]=col[rt]; xxor[rt<<1]=xxor[rt<<1|1]=0; init(rt<<1,m-(m>>1),col[rt]); init(rt<<1|1,(m>>1),col[rt]); col[rt]=-1; } else if(xxor[rt]){ if(col[rt<<1]!=-1){ col[rt<<1]^=1; init(rt<<1,m-(m>>1),col[rt<<1]); } else { xxor[rt<<1]^=1; change(rt<<1); } if(col[rt<<1|1]!=-1){ col[rt<<1|1]^=1; init(rt<<1|1,(m>>1),col[rt<<1|1]); } else { xxor[rt<<1|1]^=1; change(rt<<1|1); } xxor[rt]=0; } } void update(int L,int R,int cmd,int l,int r,int rt){ if(L<=l&&r<=R){ if(cmd<=1){ xxor[rt]=0;//取消异或标记 col[rt]=cmd;//真个区间被完全覆盖为cmd init(rt,r-l+1,cmd); } else { if(col[rt]!=-1){//被完全覆盖,全是0或者全是1,相当于取反 col[rt]^=1; init(rt,r-l+1,col[rt]); } else { xxor[rt]^=1; change(rt); } } return ; } pushdown(rt,r-l+1); int m=(l+r)>>1; if(L<=m) update(L,R,cmd,lson); if(R>m) update(L,R,cmd,rson); pushup(rt,r-l+1); } int query1(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R) return num1[rt]; pushdown(rt,r-l+1); int m=(l+r)>>1; int ans=0; if(L<=m) ans+=query1(L,R,lson); if(R>m) ans+=query1(L,R,rson); return ans; } int query2(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R) { return mx1[rt]; } pushdown(rt,r-l+1); int m=(l+r)>>1; if(R<=m) return query2(L,R,lson); if(L>m) return query2(L,R,rson); int a=query2(L,R,lson); int b=query2(L,R,rson); a=a>b?a:b; b=min(m-L+1,rb1[rt<<1])+min(R-m,lb1[rt<<1|1]); return a>b?a:b; } int main(){ int t,n,m,op,a,b; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); build(0,n-1,1); while(m--){ scanf("%d%d%d",&op,&a,&b); if(op<=2) update(a,b,op,0,n-1,1); else { if(op==3) printf("%d\n",query1(a,b,0,n-1,1)); else printf("%d\n",query2(a,b,0,n-1,1)); } } } return 0; }
相关文章推荐
- HDU 3397 Sequence operation(线段树的区间合并)
- hdu 3397 Sequence operation(线段树)
- hdu 3397 Sequence operation 线段树 区间和 连续1的个数
- hdu 3397 Sequence operation(线段树:区间更新)
- hdu 3397(线段树综合题)
- hdu 3397 Sequence Operation 线段树维护区间前后缀和,求子区间连续最值
- hdu 3397 Sequence operation 线段树
- 线段树 HDU 3397 Sequence operation
- HDU 3397 线段树
- hdu 3397 Sequence operation(线段树)
- POJ 3667 & HDU 3308 & HDU 3397 线段树的区间合并
- HDU 3397 Sequence operation (线段树,成段更新,区间合并)
- 【线段树】HDU 3397 Sequence operation 区间合并
- hdu 3397 Sequence operation(很有意思的线段树题)
- hdu 3397 Sequence operation 线段树 区间更新 区间合并
- HDU 3397 线段树 较麻烦
- 【线段树】HDU 3397 Sequence operation 区间合并
- HDU 3397 线段树区间染色 区间查询
- hdu 3397 线段树前后缀blahblah Sequence operation
- HDU 3397 - Sequence operation(线段树+区间合并)