zoukankan      html  css  js  c++  java
  • fzu 2171 线段树 lazy标记

     http://acm.fzu.edu.cn/problem.php?pid=2171
     
     
                                                                   Problem 2171 防守阵地 II

    Accept: 73    Submit: 256
    Time Limit: 3000 mSec    Memory Limit : 32768 KB

    Problem Description

    部队中总共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,指挥部将选择M个士兵依次进入指定地点进行防守任务,获得的参考指数即为M个士兵的能力之和。随着时间的推移,指挥部将下达Q个指令来替换M个进行防守的士兵们,每个参加完防守任务的士兵由于疲惫等原因能力指数将下降1。现在士兵们排成一排,请你计算出每次进行防守的士兵的参考指数。

    Input

    输入包含多组数据。

    输入第一行有两个整数N,M,Q(1<=N<=100000,1<=M<=1000,1<=Q<=100000),第二行N个整数表示每个士兵对应的能力指数Xi(1<=Xi<=1000)。

    接下来Q行,每行一个整数X,表示在原始队列中以X为起始的M个士兵替换之前的士兵进行防守。(1<=X<=N-M+1)

    对于30%的数据1<=M,N,Q<=1000。

    Output

    输出Q行,每行一个整数,为每次指令执行之后进行防守的士兵参考指数。

    Sample Input

    5 3 3 2 1 3 1 4 1 2 3

    Sample Output

    6 3 5
     
     
     
    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #define maxx 100002
    using namespace std;
    
    struct node{int l,r,color,sum;}tree[maxx*4];
    
    void build(int left,int right,int k)
    {
        tree[k].l=left;
        tree[k].r=right;
        tree[k].color=0;
        if(left==right)
        {
            scanf("%d",&tree[k].sum);
            return;
        }
        int m;
        m=(left+right)/2;
        build(left,m,k*2);
        build(m+1,right,k*2+1);
        tree[k].sum=tree[k*2].sum+tree[k*2+1].sum;
    }
    
    void pushdown(int k)
    {
        tree[k*2].sum-=(tree[k*2].r-tree[k*2].l+1)*tree[k].color;
        tree[k*2+1].sum-=(tree[k*2+1].r-tree[k*2+1].l+1)*tree[k].color;
        tree[k*2].color+=tree[k].color;
        tree[k*2+1].color+=tree[k].color;
    }
    
    int sum(int left,int right,int k)
    {
        if(tree[k].l==left&&tree[k].r==right)
            return tree[k].sum;
        if(tree[k].color)
        {
            pushdown(k);
            tree[k].color = 0;
        }
        int m;
        m=(tree[k].l+tree[k].r)/2;
        if(right<=m)
            return sum(left,right,k*2);
        if(left>=m+1)
            return sum(left,right,k*2+1);
        return sum(left,m,k*2)+sum(m+1,right,k*2+1);
    }
    
    void update(int left,int right,int k)
    {
        if(tree[k].l==left&&tree[k].r==right)
        {
            tree[k].sum-=tree[k].r-tree[k].l+1;
            tree[k].color++;
            return ;
        }
        int m;
        m=(tree[k].l+tree[k].r)/2;
        if(right<=m)
            update(left,right,k*2);
        else if(left>=m+1)
            update(left,right,k*2+1);
        else
        {
            update(left,m,k*2);
            update(m+1,right,k*2+1);
    
        }tree[k].sum=tree[k*2].sum+tree[k*2+1].sum;
    }
    
    
    
    int main()
    {
        int i,j,n,m,t,q,a,b;
        while(~scanf("%d%d%d",&n,&m,&q))
        {
            build(1,n,1);
            while(q--)
            {
                //printf("1");
                scanf("%d",&a); //printf(" er ");
                b=a+m-1;
                printf("%d
    ",sum(a,b,1));//printf("sdfd");
                update(a,b,1);//printf("okok");
            }
        }
    }
  • 相关阅读:
    实验六 进程基础
    实验五 shell脚本编程
    实验四 Linux系统搭建C语言编程环境
    实验三 Linux系统用户管理及VIM配置
    实验二 Linux系统简单文件操作命令
    实验一 Linux系统与应用准备
    实验八 进程间的通信
    实验七 信号
    实验六 进程基础
    实验五 shell脚本编程
  • 原文地址:https://www.cnblogs.com/assult/p/3709870.html
Copyright © 2011-2022 走看看