哈理工 oj 1161 Leyni

Leyni
Time Limit: 3000 MSMemory Limit: 65536 K
Total Submit: 466(94 users)Total Accepted: 142(88 users)Rating: Special Judge: No
Description

Leyni被人掳走,身在水深火热之中...
小奈叶为了拯救Leyni,独自一人前往森林深处从静竹手中夺回昏迷中的Leyni。
历经千辛万苦,小奈叶救出了Leyni,但是静竹为此极为恼怒,决定对他们发起最强烈的进攻。
不过小奈叶有一个叫做能量保护圈的道具,可以保护他们。
这个保护圈由n个小的小护盾围成一圈,从1到n编号。当某一块小护盾受到攻击的时候,小护盾就会抵消掉这次攻击,也就是说对这一块小护盾的攻击是无效攻击,从而保护圈里的人,不过小护盾在遭到一次攻击后,需要t秒进行冷却,在冷却期间受到的攻击都是有效攻击,此时他们就会遭到攻击, 即假设1秒时受到攻击并成功防御,到1+t秒时冷却才结束并能进行防御,在2到t受到的都是有效攻击。

现在小奈叶专心战斗,Leyni昏迷,他们无法得知小护盾遭受的有效攻击次数,他们需要你的帮助。
只要能帮到他们,Leyni就会赠送出一份小奈叶写真集。
Input

第一行是一个整数T,表示有多少组测试数据。
第一行是三个整数,n,q,t,n表示保护圈的长度,q表示攻击的询问的总次数,t表示能量盾的冷却时间。
接下来的q行,每行表示受到的攻击或者她询问某范围内的能量盾被攻击的次数。
攻击:
Attack   a
表示编号为a的小护盾受到一次攻击, 保证 1 <= a <= n
询问:
Query  a  b
表示询问编号从a到b的小护盾(包括a和b)总共受到了多少次有效攻击。保证 1<=a,b<=n
第k次攻击发生在第k秒,询问不花费时间。
1 <= n,q <=100000
1 <= t <= 50。

Output

每一组测试数据,先输出一行"Case i:",i表示第i组测试数据,从1开始计数。
之后对于每一个询问,输出该范围内的小护盾受到的有效攻击次数,一个询问一行。

Sample Input

1
4 7 3
Attack 1
Attack 1
Attack 1
Attack 2
Attack 2
Query 1 4
Query 1 1

Sample Output

Case 1:
3
2

Author

黄李龙

 

这个题目有一处不好处理那么就是存在一个冷却时间,写了一个超时的版本,实在不行然后,参考了下课件上的代码,佩服啊。别人代码核心在于维护了一个保存最初冷却时间的数组。

我的:

#include<iostream>
#include<stdio.h>
#include<map>
#include<string.h>
using namespace std;
const int M=100000+32;
int cnt[M];

int lowbit(int x)
{
    return x&(-x);
}

long long  sum(int x)
{
    long long s=0;
    while(x>0)
    {
        s+=cnt[x];
        x-=lowbit(x);
    }
    return s;
}

void add(int x,int val)
{
    while(x<=M)
    {
        cnt[x]+=val;
        x+=lowbit(x);
    }
}

int main()
{
     char buf[23];
    int T,n,q,t,temp1,temp2,xx=0;
    scanf("%d",&T);
    while(T--)
    {

        scanf("%d%d%d",&n,&q,&t);
        printf("Case %d:\n",++xx);
        map<int,int>dict;
        memset(cnt,0,sizeof(cnt));
        for(int k=1;k<=n;k++)
dict[k]=0;
        for(int i=0; i<q; i++)
        {
            scanf("%s",buf);
            if(buf[0]=='A')
            {
                scanf("%d",&temp1);
                if(dict[temp1]==0)
                {

                    dict[temp1]++;

                }
               else if(dict[temp1]!=t)
                {
                    add(temp1,1);
                    dict[temp1]++;
                }

                else if(dict[temp1]==t)
                {
                    dict[temp1]=0;
                }
            }
            for(int it=1; it<=n; it++)
            {
                if(dict[it]>0&&it!=temp1)
                {
                    dict[it]++;
                    if(dict[it]==t)
                        dict[it]=0;
                }

            }

            if(buf[0]=='Q')
            {
                scanf("%d%d",&temp1,&temp2);
                if(temp1>temp2)
                    swap(temp1,temp2);
                printf("%lld\n",sum(temp2)-sum(temp1-1));
            }
        }

    }
    return 0;
}

AC:


#include<iostream>
#include<stdio.h>

#include<string.h>
using namespace std;
const int M=100000+32;
int cnt[M];


int lowbit(int x)
{
    return x&(-x);
}

long long  sum(int x)
{
    long long s=0;
    while(x>0)
    {
        s+=cnt[x];
        x-=lowbit(x);
    }
    return s;
}

void add(int x,int val)
{
    while(x<=M)
    {
        cnt[x]+=val;
        x+=lowbit(x);
    }
}

int main()
{
    char buf[23];
    int T,n,q,t,temp1,temp2,xx=0;
    scanf("%d",&T);
    while(T--)
    {

        scanf("%d%d%d",&n,&q,&t);
        printf("Case %d:\n",++xx);
        int p[M];
        for(int l=0; l<=n; l++)
        {
            p[l]=-t;
        }
        memset(cnt,0,sizeof(cnt));
        int attack_cnt=0;
        for(int i=0; i<q; i++)
        {
            scanf("%s",buf);
            if(buf[0]=='A')
            {
                attack_cnt++;
                scanf("%d",&temp1);

                if(p[temp1]+t<=attack_cnt)//就是说如果发现冷却时间已经过了,那么这次完全
                    p[temp1]=attack_cnt;//可以防御,并这时候更新最初冷却时间
                else
                    add(temp1,1);
            }

            if(buf[0]=='Q')
            {
                scanf("%d%d",&temp1,&temp2);
                if(temp1>temp2)
                    swap(temp1,temp2);
                printf("%lld\n",sum(temp2)-sum(temp1-1));
            }
        }

    }
    return 0;
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值