zoukankan      html  css  js  c++  java
  • [CSP-S模拟测试]:Weed(线段树)

    题目描述

    $duyege$的电脑上面已经长草了,经过辨认上面有金坷垃的痕迹。
    为了查出真相,$duyege$准备修好电脑之后再进行一次金坷垃的模拟实验。
    电脑上面有若干层金坷垃,每次只能在上面撒上一层高度为$v_i$的金坷垃,或者除掉最新$v_i$层(不是量)撒的金坷垃。如果上面只留有不足$v_i$层金坷垃,那么就相当于电脑上面没有金坷垃了。
    $duyege$非常严谨,一开始先给你$m$个上述操作要你依次完成。然后又对实验步骤进行了$q$次更改,每次更改都会改变其中一个操作为另外一个操作。每次修改之后都会询问最终金坷垃的量有多少。


    输入格式

    输入第一行为两个正整数$m$、$q$,接下来$m$行每行$2$个整数$k$、$v_i$。$k$为$0$时撒金坷垃,为$1$时除金坷垃。接下来$q$行每行$3$个整数$c_i$、$k$、$v_i$,$c_i$代表被更改的操作是第$c_i$个,后面$2$个数描述更改为这样的操作。


    输出格式

    输出$q$行代表每次金坷垃的量为多少。


    样例

    样例输入

    10 5
    0 10
    1 5
    0 13
    0 18
    0 2
    1 1
    0 8
    0 9
    1 3
    0 7
    9 0 3
    10 1 7
    6 0 8
    10 0 5
    8 1 2

    样例输出

    58
    0
    0
    66
    41


    数据范围与提示

    对于$30%$的数据$mleqslant 1,000,qleqslant 1,000$。
    对于另外$20%$的数据,每次$k=1$时都会将金坷垃清空。
    对于$100%$的数据,$mleqslant 2 imes {10}^5,qleqslant 2 imes {10}^5,v_ileqslant {10}^4$。


    题解

    首先,来解释一下题意,在更改操作之后就不改回来啦。

    $30%$算法:

    暴力修改,每次都暴力扫一遍统计答案。

    时间复杂度:$Theta(m imes q)$。

    期望得分:$30$分。

    实际得分:$30$分。

    $100%$算法:

    利用线段树维护以下四个值:

    $alpha.$区间内加数总和$sum$。

    $eta.$当前区间向前删除数字的数量$del$。

    $gamma.$当前区间内“净”加的元素数$add$。

    $delta.$当前区间被右兄弟删除后的总和$fla$(只对左儿子维护这个信息即可)。

    每次询问就是输出$sum[1]$。

    之后就是代码实现的问题了,主要是$pushup$函数比较难搞。

    时间复杂度:$Theta(Nlog N+Qlog^2N)$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    $30%$算法:

    #include<bits/stdc++.h>
    using namespace std;
    int m,q;
    pair<bool,int> e[200001];
    int sta[200001],top;
    int ans;
    int main()
    {
    	scanf("%d%d",&m,&q);
    	for(int i=1;i<=m;i++)
    		scanf("%d%d",&e[i].first,&e[i].second);
    	while(q--)
    	{
    		ans=0;
    		top=0;
    		int c,k,v;
    		scanf("%d%d%d",&c,&k,&v);
    		e[c]=make_pair(k,v);
    		for(int i=1;i<=m;i++)
    			if(e[i].first==1)for(int j=1;j<=e[i].second;j++)if(top)top--;else break;
    			else sta[++top]=e[i].second;
    		for(int i=1;i<=top;i++)ans+=sta[i];
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

    $100%$算法:

    #include<bits/stdc++.h>
    #define L(x) x<<1
    #define R(x) x<<1|1
    using namespace std;
    int m,q;
    int c,k,v;
    pair<bool,int> e[200001];
    int tradd[1000000],trdel[1000000],trfla[1000000],trsum[1000000];
    int ask(int x,int w)
    {
    	if(w<tradd[R(x)])return trfla[L(x)]+ask(R(x),w);
    	if(w==tradd[R(x)])return trfla[L(x)];
    	if(w>tradd[R(x)])return ask(L(x),w-tradd[R(x)]+trdel[R(x)]);
    }
    void pushup(int x)
    {
    	if(tradd[L(x)]<=trdel[R(x)])
    	{
    		trfla[L(x)]=0;
    		tradd[x]=tradd[R(x)];
    		trdel[x]=trdel[L(x)]+trdel[R(x)]-tradd[L(x)];
    		trsum[x]=trsum[R(x)];
    	}
    	else
    	{
    		if(trdel[R(x)])trfla[L(x)]=ask(L(x),trdel[R(x)]);
    		else trfla[L(x)]=trsum[L(x)];
    		tradd[x]=tradd[L(x)]+tradd[R(x)]-trdel[R(x)];
    		trdel[x]=trdel[L(x)];
    		trsum[x]=trfla[L(x)]+trsum[R(x)];
    	}
    }
    void build(int x,int l,int r)
    {
    	if(l==r)
    	{
    		if(e[l].first)trdel[x]=e[l].second;
    		else
    		{
    			tradd[x]=1;
    			trsum[x]=e[l].second;
    			trfla[x]=e[l].second;
    		}
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(L(x),l,mid);
    	build(R(x),mid+1,r);
    	pushup(x);
    }
    void clear(int x){tradd[x]=trdel[x]=trsum[x]=trfla[x]=0;}
    void change(int x,int l,int r,int w)
    {
    	if(l==r)
    	{
    		clear(x);
    		if(e[l].first)trdel[x]=e[l].second;
    		else
    		{
    			tradd[x]=1;
    			trsum[x]=e[l].second;
    			trfla[x]=e[l].second;
    		}
    		return;
    	}
    	int mid=(l+r)>>1;
    	if(w<=mid)change(L(x),l,mid,w);
    	else change(R(x),mid+1,r,w);
    	pushup(x);
    }
    int main()
    {
    	scanf("%d%d",&m,&q);
    	for(int i=1;i<=m;i++)
    		scanf("%d%d",&e[i].first,&e[i].second);
    	build(1,1,m);
    	while(q--)
    	{
    		scanf("%d%d%d",&c,&k,&v);
    		e[c]=make_pair(k,v);
    		change(1,1,m,c);
    		printf("%d
    ",trsum[1]);
    	}
    	return 0;
    }
    

    rp++

  • 相关阅读:
    数学+高精度 ZOJ 2313 Chinese Girls' Amusement
    最短路(Bellman_Ford) POJ 1860 Currency Exchange
    贪心 Gym 100502E Opening Ceremony
    概率 Gym 100502D Dice Game
    判断 Gym 100502K Train Passengers
    BFS POJ 3278 Catch That Cow
    DFS POJ 2362 Square
    DFS ZOJ 1002/HDOJ 1045 Fire Net
    组合数学(全排列)+DFS CSU 1563 Lexicography
    stack UVA 442 Matrix Chain Multiplication
  • 原文地址:https://www.cnblogs.com/wzc521/p/11335541.html
Copyright © 2011-2022 走看看