当前位置:编程学习 > C/C++ >>

hdu 4339 Query 线段树 多校联合赛(四) 第九题

比赛的时候一顿wa啊!好伤
先将两个数组对位比较,相等为1,否则为零,把这个01数组挂在线段树的末节点上,然后就是向上更新啦
线段树,线段有两个属性,ml存放该线段左边最大连续长度,mr存放该线段右边最大连续长度,在向上更新的时候是a[i].mr=a[i*2+1].mr;    a[i].ml=a[i*2].ml;  这个好理解吧,但如果左孩子是全连续(这条线段的长度等于左连续长度等于右连续长度),a[i].ml=a[i*2].ml(其实这个值就是这条线段的长度)+a[i*2+1].ml;  右孩子是全连续的情况同理
insert比较好弄,就是往那个末节点改成1或0,然后同理向上更新
query的时候,如果查询x,就找到以x为右节点的线段,因为值查询x右边的连续个数,找到那条线段之后,向上加右边线段的ml(左连续值),当右边线段不是全连续的时候,再向上就不加值了,因为左连续已经断了
程序中的query全写成querry了,好囧
[cpp] 
#include<iostream> 
#include<cstdio> 
#include<string.h> 
using namespace std; 
#define N 1000005 
struct node{ 
    int l,r,ml,mr; 
}a[N*3]; 
char ca[N],cb[N]; 
int sum,num[N],x,sign; 
void build(int i,int left,int right){ 
    a[i].l=left; 
    a[i].r=right; 
    if(a[i].l==a[i].r) { 
        if(num[a[i].l]==1) 
            a[i].ml=a[i].mr=1; 
        else 
            a[i].ml=a[i].mr=0; 
        return ; 
    } 
    int mid=(a[i].l+a[i].r)>>1; 
    build(i*2,left,mid); 
    build(i*2+1,mid+1,right); 
    if(a[i*2+1].r-a[i*2+1].l+1==a[i*2+1].ml) 
        a[i].mr=a[i*2].mr+a[i*2+1].ml; 
    else 
        a[i].mr=a[i*2+1].mr; 
    if(a[i*2].r-a[i*2].l+1==a[i*2].ml) 
        a[i].ml=a[i*2].ml+a[i*2+1].ml; 
    else 
        a[i].ml=a[i*2].ml; 

void insert(int i,int x,int y){ 
    if(a[i].l==a[i].r&&a[i].l==x){ 
        a[i].ml=a[i].mr=y; 
        return ; 
    } 
    int mid=(a[i].l+a[i].r)>>1; 
    if(x<=mid) insert(i*2,x,y); 
    else insert(i*2+1,x,y); 
    if(a[i*2+1].r-a[i*2+1].l+1==a[i*2+1].ml) 
        a[i].mr=a[i*2].mr+a[i*2+1].ml; 
    else 
        a[i].mr=a[i*2+1].mr; 
    if(a[i*2].r-a[i*2].l+1==a[i*2].ml) 
        a[i].ml=a[i*2].ml+a[i*2+1].ml; 
    else 
        a[i].ml=a[i*2].ml; 

void querry(int i,int x){ 
    if(a[i].r==x){ 
        sum=1; 
        return ; 
    } 
    int mid=(a[i].l+a[i].r)>>1; 
    if(x<=mid) querry(i*2,x); 
    else querry(i*2+1,x); 
    if(a[i*2].mr!=0&&a[i*2+1].ml!=0&&sign==0&&x<a[i*2+1].l)//如果要查询的点到了右边线段,就不能在加该线段的右面线段了,以为不是一个树枝上的 
        sum+=a[i*2+1].ml; 
    if((a[i*2+1].r-a[i*2+1].l+1)!=a[i*2+1].ml&&x<=a[i*2].r) 
        sign=1; 

int main(){ 
//   freopen("in.txt","r",stdin); 
    int t,pp=1; 
    scanf("%d",&t); 
    while(t--){ 
        printf("Case %d:\n",pp++); 
        scanf("%s%s",ca,cb); 
        int lena=strlen(ca); 
        int lenb=strlen(cb); 
        int len=lena>lenb? lena:lenb; 
        for(int i=0;i<len;i++){ 
            if(ca[i]==cb[i]) 
                num[i]=1; 
            else 
                num[i]=0; 
        } 
        build(1,0,len-1); 
        int q,y,z; 
        char te[2]; 
        scanf("%d",&q); 
        while(q--){ 
            scanf("%d",&z); 
            if(z==2){ 
                scanf("%d",&x); 
                if(num[x]==0){ 
                    printf("0\n"); 
                    continue; 
                } www.zzzyk.com
                sum=0,sign=0; 
                querry(1,x); 
 
                printf("%d\n",sum); 
            }else{ 
                scanf("%d%d%s",&x,&y,te); 
                if(x==1){ 
                    ca[y]=te[0]; 
                    if(ca[y]==cb[y]) num[y]=1; 
                    else num[y]=0; 
            
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,