• BZOJ4293: [PA2015]Siano


    好像这几天的SAM的博客都忘记更了 咕咕咕(有时间补上

    言归正传 这个题主要的性质是 相对增长趋势不会发生变化 那我们根据操作的性质 可以得出 每个时刻都满足初始状态下增长趋势的相对大小关系 就是说初始值大的在接下来的时刻也一定会大因此我们可以按照这个方式去建线段树 然后维护每次查询后每个位置初始值即可 普通的线段树操作

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=5e5+10;
    const double eps=1e-8;
    #define ll long long
    using namespace std;
    //struct edge{int t;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
    //void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;}
    ll read(){
    	ll x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    	return x*f;
    }
    ll flag[MAXN<<2],add[MAXN<<2],minn[MAXN<<2],sum1[MAXN<<2],sum2[MAXN<<2],a[MAXN]; //sum1 cs sum2 zeng
    void up(int x){
    	minn[x]=min(minn[x<<1],minn[x<<1|1]);
    	sum1[x]=sum1[x<<1]+sum1[x<<1|1];
    	sum2[x]=sum2[x<<1]+sum2[x<<1|1];
    }
    void built(int rt,int l,int r){
    	flag[rt]=-1;add[rt]=minn[rt]=sum1[rt]=0;
    	if(l==r){sum2[rt]=a[l];return ;}
    	int mid=(l+r)>>1;
    	built(rt<<1,l,mid);
    	built(rt<<1|1,mid+1,r);
    	up(rt);
    }
    void push(int x,int l,int r){
    	int mid=(l+r)>>1;
    	if(flag[x]!=-1){
    		add[x<<1]=add[x<<1|1]=0;flag[x<<1]=flag[x<<1|1]=flag[x];
    		minn[x<<1]=minn[x<<1|1]=flag[x];sum1[x<<1]=1LL*(mid-l+1)*flag[x];sum1[x<<1|1]=1LL*(r-mid)*flag[x];
    		flag[x]=-1;
    	}
    	if(add[x]!=0){
    		add[x<<1]+=add[x];add[x<<1|1]+=add[x];minn[x<<1]+=1LL*add[x]*a[l];minn[x<<1|1]+=1LL*add[x]*a[mid+1];
    		sum1[x<<1]+=sum2[x<<1]*add[x];sum1[x<<1|1]+=sum2[x<<1|1]*add[x];
    		add[x]=0;
    	}
    }
    void update1(int rt,int l,int r,int ql,int qr,ll t){
    	if(ql<=l&&r<=qr){add[rt]+=t;minn[rt]+=1LL*t*a[l];sum1[rt]+=1LL*sum2[rt]*t;return ;}
    	int mid=(l+r)>>1;
    	push(rt,l,r);
    	if(ql<=mid)update1(rt<<1,l,mid,ql,qr,t);
    	if(qr>mid)update1(rt<<1|1,mid+1,r,ql,qr,t);
    	up(rt);
    }
    void update2(int rt,int l,int r,int ql,int qr,ll t){
    	if(ql<=l&&r<=qr){add[rt]=0;flag[rt]=t;minn[rt]=t;sum1[rt]=1LL*t*(r-l+1);return ;}
    	int mid=(l+r)>>1;
    	push(rt,l,r);
    	if(ql<=mid)update2(rt<<1,l,mid,ql,qr,t);
    	if(qr>mid)update2(rt<<1|1,mid+1,r,ql,qr,t);
    	up(rt);
    }
    ll ans1,ans2,key,Time;int id;
    void Find(int x,int l,int r){
    	if(l==r){
    		if(minn[x]+1LL*Time*a[l]>=key){ans1+=sum1[x];ans2+=sum2[x];id=l;}
    		return ;
    	}
    	int mid=(l+r)>>1;
    	push(x,l,r);
    	if(minn[x<<1|1]+1LL*Time*a[mid+1]>=key){ans1+=sum1[x<<1|1];ans2+=sum2[x<<1|1];id=mid+1;Find(x<<1,l,mid);}
    	else Find(x<<1|1,mid+1,r);
    	up(x);
    }
    int main(){
    	int n,m;n=read();m=read();
    	for(int i=1;i<=n;i++)a[i]=read();
    	sort(a+1,a+n+1);built(1,1,n);ll d,b,last=0;
    	while(m--){
    		d=read();b=read();Time=d-last;key=b;ans1=ans2=id=0;Find(1,1,n);
    		if(!id){puts("0");continue;}
    		ll ans=ans1+ans2*Time-1LL*(n-id+1)*b;
    		printf("%lld
    ",ans);
    		if(id!=1)update1(1,1,n,1,id-1,Time);
    		update2(1,1,n,id,n,b);
    		last=d;
    	}
    }
    

     


    4293: [PA2015]Siano

    Time Limit: 30 Sec  Memory Limit: 256 MB
    Submit: 665  Solved: 237
    [Submit][Status][Discuss]

    Description

    农夫Byteasar买了一片n亩的土地,他要在这上面种草。
    他在每一亩土地上都种植了一种独一无二的草,其中,第i亩土地的草每天会长高a[i]厘米。
    Byteasar一共会进行m次收割,其中第i次收割在第d[i]天,并把所有高度大于等于b[i]的部分全部割去。Byteasar想知道,每次收割得到的草的高度总和是多少,你能帮帮他吗?
     

    Input

    第一行包含两个正整数n,m(1<=n,m<=500000),分别表示亩数和收割次数。
    第二行包含n个正整数,其中第i个数为a[i](1<=a[i]<=1000000),依次表示每亩种植的草的生长能力。
    接下来m行,每行包含两个正整数d[i],b[i](1<=d[i]<=10^12,0<=b[i]<=10^12),依次描述每次收割。
    数据保证d[1]<d[2]<...<d[m],并且任何时刻没有任何一亩草的高度超过10^12。
     

    Output

    输出m行,每行一个整数,依次回答每次收割能得到的草的高度总和。
     

    Sample Input

    4 4
    1 2 4 3
    1 1
    2 2
    3 0
    4 4

    Sample Output

    6
    6
    18
    0

    HINT

    第1天,草的高度分别为1,2,4,3,收割后变为1,1,1,1。

    第2天,草的高度分别为2,3,5,4,收割后变为2,2,2,2。

    第3天,草的高度分别为3,4,6,5,收割后变为0,0,0,0。

    第4天,草的高度分别为1,2,4,3,收割后变为1,2,4,3。

     

  • 相关阅读:
    xcode swift对应版本
    VM12安装OS X10.11步骤及说明
    Java开发Webservice的组件
    xml文件格式说明
    android开发中在界面上实现曲线图的几个开源项目
    C#中SQL Server数据库连接池使用及连接字符串部分关键字使用说明
    c#对数据库访问完应关闭连接
    I2C VHDL程序
    数码管一些列功能的verilog实现
    PWM控制灯亮暗的verilog实现
  • 原文地址:https://www.cnblogs.com/wang9897/p/9618063.html
Copyright © 2020-2023  润新知