zoukankan      html  css  js  c++  java
  • hdu 3340 Rain in ACStar 线段树区间等差数列更新

    Rain in ACStar

    Time Limit: 1 Sec  Memory Limit: 256 MB

    题目连接

    http://acm.hust.edu.cn/problem/show/1385

    Description

    Maybe you have heard of Super Cow AC who is the great general of ACM Empire. However, do you know where he is from?

    This is one of the ten biggest secrets of this world! And it is time to expose the truth!

    Yes, Super Cow AC is from ACStar which is ten million light-year away from our earth. No one, even AC himself, knows how AC came to our home. The only memory in his head is the strange rain in ACStar.

    Because of the special gravity of ACStar, the raindrops in ACStar have many funny features. They have arbitrary sizes, color and tastes. The most interesting parts of the raindrops are their shapes. When AC was very young, he found that all the drops he saw in air were convex hull. Once the raindrops fell to the ground, they would be absorb by the soil.

    .*

    This year is set to be AC-year. In recognition of Great General AC's contribution to our empire, the Emperor decided to build a huge AC park. Inside this park there is a laboratory to simulate the rain in ACStar. As a researcher of this lab, you are appointed to measure the volume of rain absorbed by soil. To simplify this problem, scientists put the rain into two-dimensional plane in which the ground is represented as a straight line and the raindrops are convex polygon. So the area of the graphics stands for the volume of raindrops.

    You will receive two types of instructions:

    1. R P (This type of instructions tell you sufficient information about the raindrops.)
    2. Q A B (Ask you to report the volume of rain absorbed by soil of [A,B].)

    Instructions are given in chronological order.



    Input

    The first line of the inputs is T(no more than 10), which stands for the number of test cases you need to solve.
    After T, the inputs will be each test case. The first line of each case will be N(no more than 25000), representing for the numbers of instructions. The following N lines will give instructions of the two types.
    For each instruction of type 1, it will be followed by a line listing P (at least 3 and at most 5) points representing the convex polygon of the coming raindrop. The points are started by the leftmost point and are given in counterclockwise order. It's guaranteed that no points of the same raindrop are in the same vertical line.
    All numbers are positive integer no more than 1000000000.
    1000000000.

    Output

    For each instruction of type 2, output the corresponding result, which should be printed accurately rounded to three decimals.
    It is guaranteed that the result is less than 1e8.

    Sample Input

    1 7 Q 1 100 R 4 10 10 11 10 13 11 12 11 Q 10 11 Q 1 100 R 3 100 20 120 20 110 30 Q 1 100 Q 12 120

    Sample Output

    0.000
    0.250
    1.000
    1.000
    100.250

    HINT


    题意

    下凸包雨,每次会下3-6个点组成的凸包雨
    然后查询l-r区间的凸包面积和

    题解:

    直接把凸包变成矩形面积求和就好了,我们对于大于上一个点的x轴的点记为正面积,对于小于的记为负面积
    然后随便搞一搞就好了

    代码:

    //qscqesze
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define maxn 100001
    #define mod 10007
    #define eps 1e-9
    //const int inf=0x7fffffff;   //无限大
    const int inf=0x3f3f3f3f;
    /*
    inline ll read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int buf[10];
    inline void write(int i) {
      int p = 0;if(i == 0) p++;
      else while(i) {buf[p++] = i % 10;i /= 10;}
      for(int j = p-1; j >=0; j--) putchar('0' + buf[j]);
      printf("
    ");
    }
    */
    //**************************************************************************************
    
    struct node
    {
        int x[6],y[6],z,n;
    };
    node op[maxn];
    vector<int> po;
    char str[5];
    int t,n,k;
    map<int,int> H;
    struct tree
    {
        int l,r,len;
        double add1,add2,step,sum;
        void init() { add1=add2=step=sum=0; }
        void fun(double a,double b,double c)
        {
            add1+=a;    add2+=b;     step+=c;
            sum+=(a+b)*len/2;
        }
    };
    tree tree[maxn*4];
    
    double calu(int st,int ed,double add1,double step)
    {
        int len=po[ed]-po[st];
        return add1+len*step;
    }
    void PushUp(int ind)
    {
        tree[ind].sum=tree[ind<<1].sum+tree[ind<<1|1].sum;
    }
    void PushDown(int ind)
    {
            double add1=tree[ind].add1,add2=tree[ind].add2,step=tree[ind].step;
            double tmp=calu(tree[ind].l,(tree[ind].l+tree[ind].r)/2,add1,step);
            tree[ind<<1].fun(add1,tmp,step);
            tree[ind<<1|1].fun(tmp,add2,step);
            tree[ind].add1=tree[ind].add2=tree[ind].step=0;
    }
    void build(int lft,int rht,int ind)
    {
        tree[ind].l=lft;    tree[ind].r=rht;
        tree[ind].init();    tree[ind].len=po[rht]-po[lft];
        if(lft+1!=rht)
        {
            int mid=tree[ind].l+tree[ind].r>>1;
            build(lft,mid,ind<<1);
            build(mid,rht,ind<<1|1);
        }
    }
    void updata(int st,int ed,int ind,double add1,double add2,double step)
    {
        int lft=tree[ind].l,rht=tree[ind].r;
        if(st<=lft&&rht<=ed) tree[ind].fun(add1,add2,step);
        else
        {
            PushDown(ind);
            int mid=tree[ind].l+tree[ind].r>>1;
            if(ed<=mid) updata(st,ed,ind<<1,add1,add2,step);
            else if(st>=mid) updata(st,ed,ind<<1|1,add1,add2,step);
            else
            {
                double tmp=calu(st,mid,add1,step);
                updata(st,mid,ind<<1,add1,tmp,step);
                updata(mid,ed,ind<<1|1,tmp,add2,step);
            }
            PushUp(ind);
        }
    }
    double query(int st,int ed,int ind)
    {
        int lft=tree[ind].l,rht=tree[ind].r;
        if(st<=lft&&rht<=ed) return tree[ind].sum;
        else
        {
            PushDown(ind);
            int mid=tree[ind].l+tree[ind].r>>1;
            double sum=0;
            if(st<mid) sum+=query(st,ed,ind<<1);
            if(ed>mid) sum+=query(st,ed,ind<<1|1);
            PushUp(ind);
            return sum;
        }
    }
    void init()
    {
        memset(tree,0,sizeof(tree));
        po.clear();
        memset(op,0,sizeof(op));
        H.clear();
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%s",str);
            if(str[0]=='R')
            {
                op[i].z=0;
                scanf("%d",&op[i].n);
                for(int j=0;j<op[i].n;j++)
                {
                    scanf("%d%d",&op[i].x[j],&op[i].y[j]);
                    po.push_back(op[i].x[j]);
                }
            }
            else
            {
                op[i].z=1;
                scanf("%d%d",&op[i].x[0],&op[i].y[0]);
                po.push_back(op[i].x[0]);
                po.push_back(op[i].y[0]);
            }
        }
        sort(po.begin(),po.end());
        po.erase(unique(po.begin(),po.end()),po.end());
        for(int i=0;i<po.size();i++)
            H[po[i]]=i;
    }
    void solve()
    {
        for(int i=0;i<n;i++)
        {
            int x1,y1,x2,y2;
            if(op[i].z==0)
            {
                for(int j=0;j<op[i].n;j++)
                {
                    x1=op[i].x[j];
                    y1=op[i].y[j];
                    x2=op[i].x[(j+1)%op[i].n];
                    y2=op[i].y[(j+1)%op[i].n];
                    if(x1>x2)
                        swap(x1,x2),swap(y1,y2);
                    else
                        y1=-y1,y2=-y2;
                    double step=(y1*1.0-y2*1.0)/(x1*1.0-x2*1.0);
                    updata(H[x1],H[x2],1,y1,y2,step);
                }
            }
            else
            {
                x1=op[i].x[0],y1=op[i].y[0];
                printf("%.3lf
    ",query(H[x1],H[y1],1));
            }
        }
    }
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            init();
            build(0,po.size()-1,1);
            solve();
        }
    }
  • 相关阅读:
    320 Generalized Abbreviation
    319. Bulb Switcher
    三条用人原则
    Go 编码问题的解决方案
    C# MVC js 跨域
    apidoc接口文档的快速生成
    go语言学习
    C#系统之垃圾回收
    WCF项目启动时错误处理
    XML之XPath
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4427317.html
Copyright © 2011-2022 走看看