F - Count the Colors

 
思路:调了一个小时,但是发现自己线段树木有写错,颜色统计出了错误。但是不明白自己颜色统计为什么错了。
求大佬指点迷津。思路很简单,就是一个裸的线段树。只要推出样例就做出来了。
以下是两种颜色统计:
这是我的错误的:
for(int i=1;i<=8009;i++){
        if(vis[i]!=vis[i-1]&&vis[i-1]!=-1)    ans[vis[i-1]]++;
        if(i==8000&&vis[i]!=-1)    ans[vis[i-1]]++;
}

后来大佬解决了疑惑,改成酱就对了:

 

for(int i=1;i<=8009;i++)
    if(vis[i]!=vis[i-1]&&vis[i-1]!=-1)    ans[vis[i-1]]++;

 

是因为本来i就超过了最大范围,所以最后一个一定会被统计上,再加上特判就会造成重复计数。

 

这是正确的:

int i=1;
while(i<MAXN){
    int flagor=vis[i],j=i+1;
    if(flagor==-1){    ++i;continue; }
    while(vis[j]!=-1&&vis[j]==flagor&&j<MAXN) ++j;
    ++ans[flagor];i=j;
}

cpp:

 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 8010
using namespace std;
int n,m;
struct nond{
    int l,r,flag;
}tree[MAXN*4];
int vis[MAXN*4],ans[MAXN*4];
void build(int now,int l,int r){
    tree[now].l=l;tree[now].r=r;tree[now].flag=-1;
    if(tree[now].l==tree[now].r)    return ;
    int mid=(tree[now].l+tree[now].r)/2;
    build(now*2,l,mid);
    build(now*2+1,mid+1,r);
}
void down(int now){
    tree[now*2].flag=tree[now].flag;
    tree[now*2+1].flag=tree[now].flag;
    tree[now].flag=-1; return ;
}
void change(int now,int l,int r,int k){
    if(tree[now].l==l&&tree[now].r==r){
        tree[now].flag=k;
        return ;
    }
    if(tree[now].flag==k)    return ;
    if(tree[now].flag!=-1)    down(now);
    int mid=(tree[now].l+tree[now].r)/2;
    if(r<=mid)    change(now*2,l,r,k);
    else if(l>mid)    change(now*2+1,l,r,k);
    else{ change(now*2,l,mid,k);change(now*2+1,mid+1,r,k); }
}
void query(int now){
    if(tree[now].flag!=-1){
        for(int i=tree[now].l;i<=tree[now].r;i++)
            vis[i]=tree[now].flag;
        return ;
    }
    if(tree[now].l==tree[now].r)    return ;
    query(now*2);    query(now*2+1);
}
int main(){
    while(scanf("%d",&n)!=EOF){
        memset(ans,0,sizeof(ans));
        memset(vis,-1,sizeof(vis));
        build(1,1,8000);
        for(int i=1;i<=n;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            change(1,x+1,y,z);
        }
        query(1);
        for(int i=1;i<=8009;i++)
            if(vis[i]!=vis[i-1]&&vis[i-1]!=-1)    ans[vis[i-1]]++;
        for(int i=0;i<=8009;i++)
            if(ans[i])    printf("%d %d\n",i,ans[i]);
        cout<<endl;
    }
}

 

 

 

posted @ 2018-02-25 08:43  一蓑烟雨任生平  阅读(330)  评论(0编辑  收藏  举报