1. 程式人生 > >Yandex.Algorithm 2011 Round 1(STL!)

Yandex.Algorithm 2011 Round 1(STL!)

D. Sum of Medians time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output

In one well-known algorithm of finding the k-th order statistics we should divide all elements into groups of five consecutive elements and find the median of each five. A median is called the middle element of a sorted array (it's the third largest element for a group of five). To increase the algorithm's performance speed on a modern video card, you should be able to find a sum of medians in each five of the array.

sum of medians of a sorted k-element set S = {a1, a2, ..., ak}, where a1 < a2 < a3 < ... < ak, will be understood by as 

The  operator stands for taking the remainder, that is  stands for the remainder of dividing x by y.

To organize exercise testing quickly calculating the sum of medians

 for a changing set was needed.

Input

The first line contains number n (1 ≤ n ≤ 105), the number of operations performed.

Then each of n lines contains the description of one of the three operations: 

  • add x — add the element x to the set; 
  • del x — delete the element x from the set; 
  • sum — find the sum of medians
     of the set. 

For any add x operation it is true that the element x is not included in the set directly before the operation.

For any del x operation it is true that the element x is included in the set directly before the operation.

All the numbers in the input are positive integers, not exceeding 109.

Output

For each operation sum print on the single line the sum of medians of the current set. If the set is empty, print 0.

Please, do not use the %lld specificator to read or write 64-bit integers in C++. It is preferred to use the cincout streams (also you may use the %I64d specificator).

Examples input
6
add 4
add 5
add 1
add 2
add 3
sum
output
3
input
14
add 1
add 7
add 2
add 5
sum
add 6
add 8
add 9
add 3
add 4
add 10
sum
del 1
sum
output
5
11
13

題意:

給出n個操作

.add x 表示向集合中新增x(新增x的時候保證x是第一次被新增入集合)

.del x 表示從集合中刪除x (刪除x的時候保證x存在於集合中)

.sum 將集合排序後,詢問集合裡面所有下標i % 5 = 3的元素的和(如果集合為空輸出0)

1 <= n <= 10^5

0 < x <= 1e9


題解:

這個題居然是STL解決的!  

直接使用vector的函式,del, add操作複雜度o(log(n))。 sum操作為o(n),由基本不等式得,最壞的情況,為前1e5/2 次都是add,後1e5/2次全是sum。  操作次數為 (1e5 / 2) * (1e5 / 2 / 5) = 5e8。暴力。

很奇怪的是vector如果是long long就掉了。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const int inf=0x3fffffff;
const ll mod=1000000007;
const int maxn=20+10;
vector<int> V;
int main()
{
    int n;
    scanf("%d",&n);
    rep(i,1,n+1)
    {
        char s[10];
        scanf("%s",s);
        if(s[0]=='s')
        {
            ll ans=0;
            for(int i=2;i<V.size();i+=5)
                ans+=V[i];
            printf("%lld\n",ans);
        }
        else if(s[0]=='a')
        {
            int x;
            scanf("%d",&x);
            V.insert(lower_bound(V.begin(),V.end(),x),x);
        }
        else
        {
            int x;
            scanf("%d",&x);
            V.erase(lower_bound(V.begin(),V.end(),x));
        }
    }
    return 0;
}