平衡森林

T1 鬼子进村

【题目描述】

县城里有n个用地道相连的房子,第i个只与第i-1和第i+1个相连。有m个消息依次传来:

(1)消息为:D x,鬼子将x号房子摧毁了,地道被堵上;

(2)消息为:R,村民们将鬼子上一个摧毁的房子修复了;

(3)消息为:Q x,有一名士兵被围堵在x号房子中;

现在询问每一个被围堵的士兵能够到达的房子有几个。

【输入描述】

第一行2个整数n、m(n,m <= 50000);

接下来m行,有如题所述的三种信息共m条。

【输出描述】

对于每一个被围堵的士兵,输出该士兵能够到达的房子数。

【输入样例】

7 9

D 3

D 6

D 5

Q 4

Q 5

R

Q 4

R

Q 4

【输出样例】

1

0

2

4

从来都不知道什么才叫做暴力:

源代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
stack <int> Q;
bool f[50001]={0};
int m,n,num(0),i[50001];
int Read(int &t) //读入优化,开头赋值很重要。
{
    t=0;
    char T=getchar();
    while (T>'9'||T<'0')
      T=getchar();
    while (T>='0'&&T<='9')
    {
        t=10*t+T-'0';
        T=getchar();
    }
}
int main()
{
    Read(n);
    Read(m);
    char T;
    for (int a=1;a<=m;a++)
    {
        cin>>T;
        if (T=='D')
        {
            int t;
            Read(t);
            Q.push(t);
            f[t]=true;
            i[++num]=t;
        }
        if (T=='R')
        {
            int t=Q.top();
            Q.pop();
            f[t]=false;
            sort(i+1,i+num+1);
            for (int b=1;b<=num;b++) 
              if (i[b]==t)
              {
                if (i[b]==i[num])
                  num--;
                else
                {
                      i[b]=i[num];
                    num--;
                }
                  break;
              }
        }
        if (T=='Q')
        {
            int t;
            Read(t);
            if (f[t])
              printf("0
");
            else
            {
                sort(i+1,i+num+1);
                if (t>i[num])
                  printf("%d
",n-i[num]);
                else
                  for (int b=1;b<=num;b++)
                    if (i[b]>t)
                    {
                        printf("%d
",i[b]-i[b-1]-1);
                        break;
                    }
            }
        }
    }
    return 0;
}

T2 可怜的狗狗

【题目描述】

小卡家有n只狗,每一只狗都有一个不同的漂亮值。漂亮值越低越漂亮,吃饭时,狗狗们会按顺序站成一排等着主人给食物。

可小卡不肯喂这么多狗,于是他每次就只给第i只到第j只狗中第k漂亮的狗狗喂食。而且为了保证某一只狗狗不会被喂太多次,他喂的每个区间(i,j)不互相包含。

【输入描述】

第一行输入两个数n、m(n <= 300000,m <= 50000),m表示他喂了m次;

第二行n个整数,表示第i只狗的漂亮值为ai;

接下来m行,每行3个整数i、j、k表示这次喂食喂第i到第j只狗中第k漂亮的狗的漂亮值。

【输出描述】

输出m行,每行一个整数,表示每一次喂的那只狗漂亮值为多少。

【输入样例】

7 2

1 5 2 6 3 7 4

1 5 3

2 7 1

【输出样例】

3

2

T3 送花

【题目描述】

小明一开始有一个空的花束,每朵花有一个美丽值W,价格为C,他不断地向里面添加花。他有以下几种操作:

1 W C:添加一朵美丽值为W,价格为C的花;

3:删除最便宜的一朵花;

2:删除最贵的一朵花;

-1:完成添加与删除,开始包装花束;

若删除操作时没有花,则跳过删除操作。

如果加入的花朵价格已经与花束中已有花朵价格重复,则这一朵花不能加入花束。

请你帮小明写一个程序,计算出开始包装花束时,花束中所有花的美丽值的总和,以及小明需要为花束付出的总价格。

【输入描述】

输入若干行,每行一个操作,以-1结束。

【输出描述】

输出一行,两个空格隔开的正整数,表示开始包装花束时,花束中所有花的美丽值的总和,以及小明需要为花束付出的总价格。

【输入样例】

1 1 1

1 2 5

2

1 3 3

3

1 5 2

-1

【输出样例】

8 5

【数据范围及提示】

对于全部数据,操作数 <= 100000,1 <= W,C <= 1000000。

暴力出奇迹:

源代码:

#include<cstdio>
#include<algorithm>
using namespace std;
bool f[1000001]={0};
int num(0);
struct Node
{
    int W,C;
}i[100001];
bool Rule1(const Node &t1,const Node &t2)
{
    return t1.C<t2.C;
}
bool Rule2(const Node &t1,const Node &t2)
{
    return t1.C>t2.C;
}
int main()
{
    int T;
    while (scanf("%d",&T))
    {
        if (T==1)
        {
            int W,C;
            scanf("%d%d",&W,&C);
            if (!f[C])
            {
                num++;
                i[num].W=W;
                i[0].W+=W;
                i[num].C=C;
                i[0].C+=C;
                f[C]=true;
            }
        }
        if (T==2&&num)
        {
            sort(i+1,i+num+1,Rule1);
            f[i[num].C]=false;
            i[0].W-=i[num].W;
            i[0].C-=i[num].C;
            num--;
        }
        if (T==3&&num)
        {
            sort(i+1,i+num+1,Rule2);
            f[i[num].C]=false;
            i[0].W-=i[num].W;
            i[0].C-=i[num].C;
            num--;
        }
        if (T==-1)
        {
            printf("%d %d",i[0].W,i[0].C);
            return 0;
        }
    }
}
原文地址:https://www.cnblogs.com/Ackermann/p/5796569.html