这题杯具的写了一下午,真是太菜了。。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
using namespace std;
int const N= 100010;
int n, m;
struct Node{
int Lx1, Rx1, Ax1;
int Lx0, Rx0, Ax0;
int op1, op2, op3;
int num;
};
Node tb[N<<2];
int dat[N];
void inline toRoot( int rt, int L, int R ){
int mid= (L+ R)>>1;
tb[rt].num= tb[rt<<1].num+ tb[rt<<1|1].num;
tb[rt].Ax1= max( tb[rt<<1].Ax1, tb[rt<<1|1].Ax1 );
if( tb[rt<<1].Lx1== mid- L+ 1 ) tb[rt].Lx1= tb[rt<<1].Lx1+ tb[rt<<1|1].Lx1;
else tb[rt].Lx1= tb[rt<<1].Lx1;
if( tb[rt<<1|1].Rx1== R- mid ) tb[rt].Rx1= tb[rt<<1|1].Rx1+ tb[rt<<1].Rx1;
else tb[rt].Rx1= tb[rt<<1|1].Rx1;
tb[rt].Ax1= max( tb[rt<<1].Rx1+ tb[rt<<1|1].Lx1, tb[rt].Ax1 );
tb[rt].Ax0= max( tb[rt<<1].Ax0, tb[rt<<1|1].Ax0 );
if( tb[rt<<1].Lx0== mid- L+ 1 ) tb[rt].Lx0= tb[rt<<1].Lx0+ tb[rt<<1|1].Lx0;
else tb[rt].Lx0= tb[rt<<1].Lx0;
if( tb[rt<<1|1].Rx0== R- mid ) tb[rt].Rx0= tb[rt<<1|1].Rx0+ tb[rt<<1].Rx0;
else tb[rt].Rx0= tb[rt<<1|1].Rx0;
tb[rt].Ax0= max( tb[rt<<1].Rx0+ tb[rt<<1|1].Lx0, tb[rt].Ax0 );
}
void inline Down( int rt, int L, int R ){
int mid= (L+ R)>>1;
if( tb[rt].op1 ){
tb[rt<<1].op1= tb[rt<<1|1].op1= 1;
tb[rt<<1].op2= tb[rt<<1|1].op2= 0;
tb[rt<<1].op3= tb[rt<<1|1].op3= 0;
tb[rt<<1].Lx0= tb[rt<<1].Rx0= tb[rt<<1].Ax0= mid- L+ 1;
tb[rt<<1].Lx1= tb[rt<<1].Rx1= tb[rt<<1].Ax1= 0;
tb[rt<<1].num= 0;
tb[rt<<1|1].Lx0= tb[rt<<1|1].Rx0= tb[rt<<1|1].Ax0= R- mid;
tb[rt<<1|1].Lx1= tb[rt<<1|1].Rx1= tb[rt<<1|1].Ax1= 0;
tb[rt<<1|1].num= 0;
}
if( tb[rt].op2 ){
tb[rt<<1].op2= tb[rt<<1|1].op2= 1;
tb[rt<<1].op1= tb[rt<<1|1].op1= 0;
tb[rt<<1].op3= tb[rt<<1|1].op3= 0;
tb[rt<<1].Lx0= tb[rt<<1].Rx0= tb[rt<<1].Ax0= 0;
tb[rt<<1].Lx1= tb[rt<<1].Rx1= tb[rt<<1].Ax1= mid- L+ 1;
tb[rt<<1].num= mid- L+ 1;
tb[rt<<1|1].Lx0= tb[rt<<1|1].Rx0= tb[rt<<1|1].Ax0= 0;
tb[rt<<1|1].Lx1= tb[rt<<1|1].Rx1= tb[rt<<1|1].Ax1= R- mid;
tb[rt<<1|1].num= R- mid;
}
if( tb[rt].op3 ){
tb[rt<<1].op3= 1- tb[rt<<1].op3;
tb[rt<<1|1].op3= 1- tb[rt<<1|1].op3;
int x= tb[rt<<1].Lx0, y= tb[rt<<1].Rx0, z= tb[rt<<1].Ax0;
tb[rt<<1].Lx0= tb[rt<<1].Lx1;
tb[rt<<1].Rx0= tb[rt<<1].Rx1;
tb[rt<<1].Ax0= tb[rt<<1].Ax1;
tb[rt<<1].Lx1= x; tb[rt<<1].Rx1= y; tb[rt<<1].Ax1= z;
tb[rt<<1].num= mid- L+ 1- tb[rt<<1].num;
x= tb[rt<<1|1].Lx0, y= tb[rt<<1|1].Rx0, z= tb[rt<<1|1].Ax0;
tb[rt<<1|1].Lx0= tb[rt<<1|1].Lx1;
tb[rt<<1|1].Rx0= tb[rt<<1|1].Rx1;
tb[rt<<1|1].Ax0= tb[rt<<1|1].Ax1;
tb[rt<<1|1].Lx1= x; tb[rt<<1|1].Rx1= y; tb[rt<<1|1].Ax1= z;
tb[rt<<1|1].num= R- mid- tb[rt<<1|1].num;
}
tb[rt].op1= tb[rt].op2= tb[rt].op3= 0;
}
void build( int L, int R, int rt ){
tb[rt].op1= tb[rt].op2= tb[rt].op3= 0;
if( L== R ){
if( dat[L]== 1 ) {
tb[rt].Lx1= tb[rt].Rx1= tb[rt].Ax1= 1;
tb[rt].Lx0= tb[rt].Rx0= tb[rt].Ax0= 0;
tb[rt].num= 1;
}
else {
tb[rt].Lx1= tb[rt].Rx1= tb[rt].Ax1= 0;
tb[rt].Lx0= tb[rt].Rx0= tb[rt].Ax0= 1;
tb[rt].num= 0;
}
return;
}
int mid= (L+ R)>>1;
build( L, mid, rt<<1 );
build( mid+ 1, R, rt<<1|1 );
toRoot( rt, L, R );
}
void update( int x, int y, int d, int L, int R, int rt ){
if( L!= R ) Down( rt, L, R );
if( L== x && R== y ){
if( d== 1 ){
tb[rt].op1= 1;
tb[rt].Lx0= tb[rt].Rx0= tb[rt].Ax0= R- L+ 1;
tb[rt].Lx1= tb[rt].Rx1= tb[rt].Ax1= 0;
tb[rt].num= 0;
}
else if( d== 2 ){
tb[rt].op2= 1;
tb[rt].Lx0= tb[rt].Rx0= tb[rt].Ax0= 0;
tb[rt].Lx1= tb[rt].Rx1= tb[rt].Ax1= R- L+ 1;
tb[rt].num= R- L+ 1;
}
else if( d== 3 ){
tb[rt].op3= 1;
int a= tb[rt].Lx0, b= tb[rt].Rx0, c= tb[rt].Ax0;
tb[rt].Lx0= tb[rt].Lx1;
tb[rt].Rx0= tb[rt].Rx1;
tb[rt].Ax0= tb[rt].Ax1;
tb[rt].Lx1= a; tb[rt].Rx1= b; tb[rt].Ax1= c;
tb[rt].num= R- L+ 1- tb[rt].num;
}
return;
}
int mid= (L+ R)>>1;
if( y<= mid ) update( x, y, d, L, mid, rt<<1 );
else if( x> mid ) update( x, y, d, mid+ 1, R, rt<<1|1 );
else{
update( x, mid, d, L, mid, rt<<1 );
update( mid+ 1, y, d, mid+ 1, R, rt<<1|1 );
}
toRoot( rt, L, R );
}
int query( int x, int y, int d, int L, int R, int rt ){
if( L!= R ) Down( rt, L, R );
if( x== L && y== R ){
if( d== 4 ) return tb[rt].num;
else return tb[rt].Ax1;
}
int mid= (L+ R)>>1;
if( y<= mid ) return query( x, y, d, L, mid, rt<<1 );
else if( x> mid ) return query( x, y, d, mid+ 1, R, rt<<1|1 );
else{
int a= 0, b= 0;
if( d== 4 ){
a= query( x, mid, d, L, mid, rt<<1 );
b= query( mid+ 1, y, d, mid+ 1, R, rt<<1|1 );
return a+ b;
}
else{
a= query( x, mid, d, L, mid, rt<<1 );
b= query( mid+ 1, y, d, mid+ 1, R, rt<<1|1 );
int c= min( mid- x+ 1, tb[rt<<1].Rx1 )+ min( y- mid, tb[rt<<1|1].Lx1 );
return max( a, max( b, c ) );
}
}
}
int main(){
int test;
scanf("%d",&test );
while( test-- ){
scanf("%d%d",&n,&m );
for( int i= 1; i<= n; ++i ) scanf("%d", dat+ i );
build( 1, n, 1 );
for( int i= 0; i< m; ++i ){
int op, a, b;
scanf("%d%d%d", &op, &a, &b );
a++; b++; op++;
if( op<= 3 )
update( a, b, op, 1, n, 1 );
else
printf("%d\n", query( a, b, op, 1, n, 1 ) );
}
}
return 0;
}
分享到:
相关推荐
hdu 1166线段树代码
hdu 1166线段树
【hdu5306】Gorgeous Sequence 线段树区间最值操作-附件资源
从简单入门到偏中等的几个题,线段树很灵活,主要懂了lazy操作,其他的自己yy吧。
线段树入门资料,有利于初学者学习,让他们详细了解线段树。
NULL 博文链接:https://128kj.iteye.com/blog/1738772
大量线段树题目 zoj 1610 线段覆盖 poj 2777 线段覆盖 poj 2528 需要离散化,建树不同,需要处理不同->注意这组数据 3 1 10 1 3 6 10 the ans is 3. hdu 1754 求区间最大值 hdu 1166 求区间和 hdu 1698 成段更新 ...
HDU-1711 Number Sequence(KMP算法)For each test case, you should output one line wh
300+ AC 代码 。 大数 , 线段树 , 字符串 , dp.....
HDU的1250,主要是利用高精度加法,但是代码有点繁琐,效率不是很高
题面 【题目描述】 有nnn个营地,已知每个营地的人数,有四条命令: (1)Add(1) Add(1)Add iii jjj,iii和jjj为正整数,表示第iii个营地增加jjj个人(jjj不超过303030) (2)Sub(2)Sub(2)Sub iii jjj ,iii和jjj为正...
杭电ACMhdu1163
HDU1059的代码
hdu1001解题报告
hdu 1574 passed sorce
HDU的一题........HDU DP动态规
hdu acm 教案 搜索入门 hdu acm 教案 搜索入门
hdu2101AC代码
http://acm.hdu.edu.cn/showproblem.php?pid=5667 题目分析 像这种递推公式的问题,n很大的时候,常用的处理方法是矩阵快速幂,但是这个好像很难构造。 博主思路如下:取对数 设k(i) = loga(f(i)) 那么 根据推导 k...