zoukankan      html  css  js  c++  java
  • P3875 [TJOI2010]被污染的河流

    链接:Miku

    -------------------------

    我记得扫描线有一道更水的例题来

    -------------------------

    扫描线,顾名思义,我们做这道题的时候,就要是用一道线来扫描一样

    这里有一堆矩阵,把每一个区间拆成上下两个线段,然后按照某一个端点排序,这道线就开始从头扫描

    到了一个矩阵开始的线,我们就更新扫描线的长度,反之减少即可

    两个线段之间的长度很明显就是区间距离*扫描线长度即可

    -----------------------------

    直接这么写只有30分,还是要用线段树维护的

    线段树可以加快我们查询扫描线长度和更新扫描线长度的速度

    ------------------------------

     这里的线段树我lazy记录的区间被修改次数,然后sum是区间长度(为1的数量),显然,根节点就是我们需要的,而且没必要写查询函数

    但是我的做法继续操作的相对行,有减必然有长度一样的加,所以我的代码中不需要pushdown(加了还错,至少我是)

    而且考虑到lazy和sum的区别,pushup会调用的更加频繁,甚至会pushup(叶子节点),然而叶子节点没有左右节点,要特判(也可能是我线段树写法的问题)

    -------------------------------

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int x1,y1,x2,y2;
    long long ans;
    struct li{
        int l;
        int r;
        long long  h;
        int f;
    }line[200005];
    int n;
    int p;
    int sum[4000005];
    int lazy[4000005];
    bool cmp(li x,li y){
        return x.h<y.h;
    }
    void pushup(int x,int l,int r){
        if(lazy[x]>=1)//如果被改了,肯定就是区间的长度了 
            sum[x]=r-l+1;
        else if(l!=r)
            sum[x]=sum[x<<1]+sum[x<<1|1];//考虑叶子节点 的问题 
        else
            sum[x]=0;
    }
    void update(int x,int l,int r,int L,int R,int d){
        if(L<=l&&r<=R){
            lazy[x]+=d;
            pushup(x,l,r);//冗长的特判不如加到一起 
            return ;
        }
        int mid=(l+r)>>1;
        if(L<=mid) update(x<<1,l,mid,L,R,d);
        if(R>mid) update(x<<1|1,mid+1,r,L,R,d);
        pushup(x,l,r);
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;++i){
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);//非常奇特的输入 
            if(x1>x2)
                swap(x1,x2);
            if(y1>y2)
                swap(y1,y2);
                //f的值是1或-1可以省事 
            if(x1==x2){
                p++;//自己造矩形 
                line[p].l=y1+1;
                line[p].r=y2;
                line[p].h=x1-1;
                line[p].f=1;
                p++;
                line[p].l=y1+1;
                line[p].r=y2;
                line[p].h=x1+1;
                line[p].f=-1;
            }
            else{
                p++;
                line[p].l=y1;
                line[p].r=y1+1;
                line[p].h=x1;
                line[p].f=1;
                p++;
                line[p].l=y1;
                line[p].r=y1+1;
                line[p].h=x2;
                line[p].f=-1;
            }
        }
        sort(line+1,line+p+1,cmp);
        for(int i=1;i<=p;++i){
            ans+=(line[i].h-line[i-1].h)*sum[1];//显然 
            update(1,0,1000005,line[i].l,line[i].r,line[i].f);//就在这省事 
        }
        cout<<ans;
        return 0;
    }
    Ac
  • 相关阅读:
    Django内置的响应类
    Django的路由规则
    Django中的中间件
    celery_2:异步任务简单使用
    celery_1:简介及定时任务简单使用
    mac系统 redis安装及常用命令
    redis连接:Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
    千分位函数percentile()和percentile_approx()
    模型评估_1—回归模型:mse、rmse、mae、r2
    Spark_4_2:Spark函数之collect、toArray和collectAsMap
  • 原文地址:https://www.cnblogs.com/For-Miku/p/12384624.html
Copyright © 2011-2022 走看看