现在的位置: 首页 > 综合 > 正文

UVA – 11402(线段树+区间离散)

2019年04月05日 ⁄ 综合 ⁄ 共 2282字 ⁄ 字号 评论关闭

本题查询区间最多1000个,可离散化(2000坐标排序后,任两个坐标之间的区间可看做一个点处理)

再次阐述线段树的惰性标记,每个区间下只可以存一个惰性标记;下推就要解决矛盾;

本题用1,0分别代表将区间全部该变为1或0; 2代表将区间所有的1改为0,所有0改为1;

                

如图所示,当一个1,0,下推时,可直接下推; 而2不可,因为他需要依赖该区间的原来的正确状态;需特殊考虑(如,2去直接覆盖1,当2再往下推就不会正确(应先下推1))

本解为暴力解,并未离散化;

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
#define lson (rt<<1),l,m
#define rson (rt<<1|1),m+1,r
const int maxn = 1024100;
int sum[maxn<<2],col[maxn<<2],st[maxn+100];
void pushup(int rt){
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void push(int rt,int m){
col[rt<<1]=col[rt<<1|1]=col[rt];
sum[rt<<1] = (m - (m >> 1)) * col[rt];
sum[rt<<1|1] = (m >> 1) * col[rt];
col[rt]=-1;
}
void pushdown(int rt,int m){
if(m==1){ col[rt]=-1; return ; }
if(col[rt]!=-1){
    if(col[rt]==2){
        sum[rt<<1]=(m - (m >> 1)) -sum[rt<<1];
        sum[rt<<1|1]=(m >> 1)-sum[rt<<1|1];
        if(col[rt<<1]==-1) col[rt<<1]=col[rt];
        else if(col[rt<<1]==2) col[rt<<1]=-1;
        else  {
                push(rt<<1,(m - (m >> 1)));
                col[rt<<1]=col[rt];
        }
        if(col[rt<<1|1]==-1) col[rt<<1|1]=col[rt];
        else if(col[rt<<1|1]==2) col[rt<<1|1]=-1;
        else {
                push(rt<<1|1,(m >> 1));
                col[rt<<1|1]=col[rt];
        }
    }
    else {
        sum[rt<<1] = (m - (m >> 1)) * col[rt];
		sum[rt<<1|1] = (m >> 1) * col[rt];
		col[rt<<1]=col[rt<<1|1]=col[rt];
    }
    col[rt]=-1;
}
}
void build(int rt,int l,int r){
col[rt]=-1;
if(l==r){
    sum[rt]=st[l];
    return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
int ql,qr,order;
void update(int rt,int l,int r){
if(ql<=l&&r<=qr){
    if(order==2){
        sum[rt]=r-l+1-sum[rt];
    } else sum[rt]=(r-l+1)*order;
    if(order==2){
        if(col[rt]==-1) col[rt]=order;
        else if(col[rt]==2) col[rt]=-1;
        else{
            push(rt,r-l+1); col[rt]=order;
        }
    } else col[rt]=order;
    return ;
}
pushdown(rt,r-l+1);
int m=(l+r)>>1;
if(ql<=m) update(lson);
if(qr> m) update(rson);
pushup(rt);
}
int ans;
void query(int rt,int l,int r){
if(ql<=l&&r<=qr){
     ans+=sum[rt];
     return ;
}
pushdown(rt,r-l+1);
int m=(l+r)>>1;
if(ql<=m) query(lson);
if(qr> m) query(rson);
}
int n;
char str[maxn];
int main()
{
    int T,kase=1;
    scanf("%d",&T);
    while(T--){
        n=1;
        int t,a,b;
        scanf("%d",&t);
        while(t--){
            scanf("%d",&a);
            scanf("%s",str);
            int len=strlen(str);
            for(int i=0;i<a;i++)
                for(int j=0;j<len;j++) st[n++]=(str[j]=='1'? 1:0);
        }
        printf("Case %d:\n",kase++);
        n--;
        build(1,1,n);
        int Q,ca=1;
        scanf("%d",&Q);
        while(Q--){
            char cmd[5];
            scanf("%s %d %d",cmd,&ql,&qr);
            ql++; qr++;
            if(cmd[0]=='S'){
                ans=0;
                query(1,1,n);
                printf("Q%d: %d\n",ca++,ans);
                continue;
            }
            if(cmd[0]=='F') order=1;
            if(cmd[0]=='E') order=0;
            if(cmd[0]=='I') order=2;
            update(1,1,n);
        }
    }
    return 0;
}

抱歉!评论已关闭.