[SinGuLaRiTy] COCI 2011~2012 #2

【SinGuLaRiTy-1007】 Copyright (c) SinGuLaRiTy 2017. All Rights Reserved.

测试题目

对于所有的题目:Time Limit:1s  |  Memory:256 MB

第一题:考试得分(score)[najboljih]

【题目描述】

某单位举办了一次考试,考试有8道题,每道题的得分不一样。选手可以随便做,但最后只统计5道题的得分。现在给出选手每道题的得分,求出他最后的得分最大是多少?

【输入】

8行,每行一个正整数X(0<=X<=150),第i个X表示第i道题的得分。

【输出】

第一行:该选手最后的得分。

第二行:按升序给出的选入计分的5道题的题号。

【样例数据】

样例输入 样例输出

20

30

50

48

33

66

0

64


261

3 4 5 6 8

【简单题解】

大水题

【STD Code】

#include<cstring>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
struct node
{
    int order;
    int value;
};
node num[10];
int sto[10];
int cnt=1;
bool cmp(node x,node y)
{
    if(x.value<y.value)
        return 1;
    return 0;
}
int main()
{
    freopen("score.in","r",stdin);
    freopen("score.out","w",stdout);
    int Ans=0;
    for(register int i=1;i<=8;i++)
    {
        scanf("%d",&num[i].value);
        num[i].order=i;
    }
    sort(num+1,num+9,cmp);
    for(register int i=4;i<=8;i++)
    {
        Ans+=num[i].value;
        sto[cnt]=num[i].order;
        cnt++;
    }
    printf("%d\n",Ans);
    sort(sto+1,sto+6);
    for(int i=1;i<=5;i++)
    {
        printf("%d ",sto[i]);
    }
    return 0;
}

【International Edition】

The Croatian version of this contest has the following rules: “Each round of the contest consists of 8 
tasks with different point values. Every contestant may solve any of the tasks they choose. However, the 
contestant’s final score will be the sum of points earned on any 5 tasks such that this sum is maximized.” 
Since the organizers were busy coming up with interesting problems for the contest (and translating 
them), they’ve simply forgotten to solve the problem of determining the points scored by each 
contestant. Now they are kindly asking you to do it for them. 
Write a program that, given the number of points earned by a contestant on each task, determines the 
total amount of points scored by that contestant, as well as the sorted list of the 5 problems counting 
towards that score. No contestant will ever score the same amount of points on two different 
problems.

INPUT

Input consists of 8 lines. Each line of input contains a single positive integer X (0 ≤ X ≤ 150), where 
the number X in row i denotes the number of points earned by the contestant on problem i. All 8 
numbers X will be distinct.

OUTPUT

The first line of output must contain the total amount of points scored by the contestant. 
The second line of output must contain indices of the 5 problems counting towards the total score, 
sorted in ascending order, separated by single spaces. Problem indices are positive integers from 1 to 
8, inclusive.

SCORING

If only the first line of output (the total amount of points) is correct, the solution will be awarded 40% 
of points on that test case (even if the second line of output is not present).

第二题:死胡同(deadend)[okret]

【题目描述】

Mirko学会了开车,但是他还不会在狭窄的街道上掉头。所以,他只能找一个禁止掉头的城镇开车。现在他已经拿到了一个城镇的地图。这个城镇可以看做是R*C的一个表格,每个格子要么为’X’,要么为’.’。’X’表示建筑的一部分,‘.’表示道路。你可以从当前格子往上下左右四个方向移动,当然,‘X’是不能进入的。如果从城镇的任一点出发,你都能找到一条路径回到原点,则认为该城镇没有死胡同,否则该城镇有死胡同,不适合Mirko开车。

【输入】

第一行包含两个整数R和C(3<=R,C<=10),表示城镇地图的行数和列数。

接下来有R行,每行C个字符,要么为’X’,要么为’.’。’X’表示建筑的一部分,‘.’表示道路。

至少有两个格子为‘.’,且保证所有‘.’都是联通的。

【输出】

唯一的一行,如果没有死胡同,输出0,否则输出1.

【样例数据】


样例输入


样例输出


4 3

XXX

X.X

X.X

XXX

1

【简单题解】

大水题,注意特殊情况即可。

【STD Code】

#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
int city[20][20];
int model[20][20];
char data[20];
int X,R;
int step_cnt=-1;
int flag=1;
void reset()
{
    for(register int i=1;i<=X;i++)
        for(register int j=1;j<=R;j++)
        {
            model[i][j]=city[i][j];
        }
}
void DFS(int x,int y)
{
    step_cnt++;
    if(step_cnt>1&&(model[x+1][y]==3||model[x-1][y]==3||model[x][y+1]==3||model[x][y-1]==3))
        flag=0;
    if(model[x][y]!=3)
        model[x][y]=0;
    if(model[x+1][y]==1)//up
    {
        DFS(x+1,y);
    }
    if(model[x-1][y]==1)//down
    {
        DFS(x-1,y);
    }
    if(model[x][y-1]==1)//left
    {
        DFS(x,y-1);
    }
    if(model[x][y+1]==1)//right
    {
        DFS(x,y+1);
    }
}
int main()
{
    scanf("%d%d",&X,&R);
    for(register int i=1;i<=X;i++)
    {
        scanf("%s",data+1);
        for(register int j=1;j<=R;j++)
        {
            city[i][j]=(data[j]==‘X‘ ? 0 : 1);
        }
    }
    for(register int i=1;i<=X;i++)
        for(register int j=1;j<=R;j++)
        {
            if(city[i][j]!=0)
            {
                reset();
                model[i][j]=3;
                DFS(i,j);
                if(flag==1)
                {
                    printf("1");
                    return 0;
                }
                flag=1;
                step_cnt=-1;
            }
        }
    printf("0");
    return 0;
}

【International Edition】

Mirko has been learning to drive, but he still cannot make a U-turn in a narrow street. That’s why he 
has decided to go practice in a town where U-turns are forbidden everywhere. This prohibition can be 
marked by the following sign:


Mirko has soon figured out that his ideal town must not contain dead-end streets, since it is impossible 
to exit such a street without a U-turn (let us assume that Mirko cannot drive in reverse either). Write a 
program to analyse a town map and determine whether the town is suitable for Mirko (i.e. whether the 
town has any dead-end streets). 
The town map is a table with R x C cells, where each cell is a building segment (denoted by X) or a 
road surface (denoted by a dot). From a road surface cell, Mirko can move to any of the surrounding 
four cells (up, down, left, or right), provided that it is also a road surface (i.e. not a building). 
Formally, we will determine that a town is free of dead-end streets if, starting from any road surface cell 
and going in any of the possible directions, we can return to the starting cell without making a 180 
degrees turn (changing our direction to the opposite one).

INPUT

The first line of input contains the positive integers R and C (3 ≤ R, C ≤ 10), the dimensions of the 
town. 
Each of the next R lines contains C characters, with each character either “X” or “.”. These R x C 
characters represent the town map as described in the text above. At least two cells will be road 
surfaces, and all road surfaces will be connected (i.e. mutually reachable).

OUTPUT

The first and only line of output must contain 0 if the town is free of dead-end streets, otherwise it 
must contain 1.

第三题:最大公约数(gcd)[zadaca]

【题目描述】

Mirko的家庭作业是求两个正整数A,B的最大公约数。因为数字太大,老师提供了N个小点的数,他们的乘积为A,又提供了M个小点的数,他们的乘积为B。

Mirko想验证他的结果,于是他请你写个程序帮帮他。

如果结果超过9位,只需输出最后的9位。

【输入】

输入格式:第一行包含一个正整数N(1<=N<=1000)

第二行包含N个空格隔开的正整数,每个整数小于1000000000,它们的乘积为A。

第三行包含正整数M(1<=M<=1000)

第四行包含M个空格隔开的正整数,每个整数小于1000000000,它们的乘积为B。

【输出】

唯一的一行,表示A和B的最大公约数。如果超过9位,只需要输出最后的9位。

【样例数据】


样例输入


样例输出


3

358572 83391967 82

3

50229961 1091444 8863

12028

【简单题解】

水题,直接因数分解一遍,再查找相同的因数(用哈希),求较小值即可,对于10^9的判定应该很容易的,注意特殊情况;

【STD Code】

#include<cstdio>
#include<algorithm>
#define MOD 1000000000
#define ll long long
using namespace std;
bool h[35005];
int p[10005];
int cnt,n,m,l,w;
ll ans=1;
int A[10005];
int B[10005];
ll ksm(ll a,int k)
{
    if(k==0)return 1ll;
    ll o=ksm(a,k/2);
    ll p=o*o;
    if(p>=MOD)
    {
        p%=MOD;
        w=1;
    }
    if(k&1)
    {
        p*=a;
        if(p>=MOD)
        {
            p%=MOD;
            w=1;
        }
    }
    return p;
}
void add(int *K,int a)
{
    for(int i=1;i<=cnt;i++)
    {
        while(a%p[i]==0)
        {
            a/=p[i];
            K[i]++;
        }
    }
    if(a>1)
    {
        p[++cnt]=a;
        K[cnt]++;
        a=1;
    }
}
int main()
{
    //freopen("gcd.in","r",stdin);
    //freopen("gcd.out","w",stdout);
    for(int i=2;i*i<=MOD;i++)
    {
        if(!h[i])
            p[++cnt]=i;
        for(int j=1;j<=cnt&&i*p[j]<=35000;j++)
            h[i*p[j]]=1;
    }
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int r;
        scanf("%d",&r);
        add(A,r);
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        int r;
        scanf("%d",&r);
        add(B,r);
    }
    for(int i=1;i<=cnt;i++)
    {
        ans*=ksm(p[i],min(A[i],B[i]));
        if(ans>=MOD)
        {
            ans%=MOD;
            w=1;
        }
    }
    if(w==1)
        printf("%09d",int(ans));
    else
        printf("%d",int(ans));
}

【International Edition】

Mirko has received a homework assignment to compute the greatest common divisor of the two 
positive integers A and B. Since the numbers are quite large, the teacher provided him with N smaller 
integers whose product is A, and M integers with product B. 
Mirko would like to verify his result, so he has asked you to write a program to solve his problem. 
If the result is more than 9 digits long, output only the last 9 digits.

INPUT

The first line of input contains the positive integer N (1 ≤ N ≤ 1000). 
The second line of input contains N space-separated positive integers less than 1 000 000 000, whose 
product is the number A. 
The third line of input contains the positive integer M (1 ≤ M ≤ 1000). 
The fourth line of input contains M space-separated positive integers less than 1 000 000 000, whose 
product is the number B.

OUTPUT

The first and only line of output must contain the greatest common divisor of numbers A and B. If the 
result is more than 9 digits long, output only the last (least significant) 9 digits.

第四题:数对(pair)[kompici]

【题目描述】

在成功的完成了家庭作业后,Mirko无聊地写下了N个数。其中有些数对是他喜欢的,有些数对是他不喜欢的。他喜欢的数对有这样一个特征:两个数中至少有一位共同的数字,不要求他们在同一位。

帮助Mirko计算他喜欢的数对有多少?

【输入】

第一行包含正整数N(1<=N<=1000000)

接下来N行,每行包含1个正整数,在区间[1,1018],表示Mirko写下的数。没有两个数是相等的。

【输出】

唯一的一行,表示Mirko喜欢的数对有多少。

【样例数据】


样例输入


样例输出


4

32

51

123

282

4

【简单题解】

需要用到容斥原理,对于开始的10^6个数,由于本质不同的只有1024个,所以可以压缩成1024种情况,这样总的复杂度就是1024*1024了

【STD Code】

#include <cstdio>
using namespace std;
typedef long long LL;
LL num[1<<12];
int n;
LL ans;
inline void Get_int(LL &Ret)
{
    char ch;
    bool flag=false;
    for(;ch=getchar(),ch<‘0‘||ch>‘9‘;)
        if(ch==‘-‘)
            flag=true;
    for(Ret=ch-‘0‘;ch=getchar(),ch>=‘0‘&&ch<=‘9‘;Ret=Ret*10+ch-‘0‘);
    flag&&(Ret=-Ret);
}
int main()
{
    scanf("%d",&n);
    LL tmp=0;
    for(int i=1;i<=n;i++) {
        tmp=0;
        Get_int(tmp);
        LL k=0;
        while(tmp>0) {
            LL t=tmp%10;
            tmp/=10;
            k|=(1<<t);
        }
        num[k]++;
    }
    for(int i=1;i<1024;i++) {
        if(num[i]==0) continue;
        for(int j=1;j<1024;j++) {
            if(i==j||num[j]==0||((i&j)==0)) continue;
            ans+=num[i]*num[j];
        }
        ans+=num[i]*(num[i]-1);
    }
    printf("%lld\n",ans/2);
    return 0;
}

【International Edition】

After successfully solving his math homework from the previous task, Mirko has become bored, so he 
has made a list of N large integers. On the list there are some pairs of numbers that he likes, and some 
pairs he doesn’t like. 
Mirko has named the pairs that he likes pals. Two numbers are pals if they have at least one digit in 
common (not necessarily in the same position). 
Help Mirko count how many pairs of numbers in his list are pals.

INPUT

The first line of input contains the positive integer N (1 ≤ N ≤ 1 000 000). 
Each of the next N lines contains a positive integer from the range [1, 1018], a number from Mirko’s 
list. No two numbers in the list will be equal.

OUTPUT

The first and only line of output must contain the number of pairs that are pals.

第五题:N-th(N-th)[funkcija]

【题目描述】

Mirko写下了下面的函数:


int fun() {

int ret = 0;

for (int a = X1; a <= Y1; ++a)

for (int b = X2; b <= Y2; ++b)

...

for (int <N-th> = XN; <N-th> <= YN; ++<N-th>)

ret = (ret + 1) % 1000000007;

return ret;

}


function fun: longint;

var

ret: longint;

a, b, ... , y, z: longint;

begin

ret := 0;

for a := X1 to Y1 do

for b := X2 to Y2 do

...

for <N-th> := XN to YN do

ret := (ret + 1) mod 1000000007;

fun := ret;

end;

<N-th>表示第t个小写字母,每个Xi和Yi要么表示整数a(0<a<=100000),要么表示一个外层某个循环变量。例如,X3可以表示a,b或一个整数。Xi和Yi中至少有一个是整数常量。

计算函数的返回值。

【输入】

第一行包含一个正整数N(1<=N<=26)

接下来N行,第i行包含Xi和Yi,用空格隔开。如果Xi和Yi都为常量,则Xi<=Yi.

【输出】

唯一的一行,包含函数的返回值。

【样例数据】


样例输入


样例输出


3

1 2

a 3

1 b

11

【简单题解】

神犇题!!巨神无比的递推!!这里面涉及到的思想需要慢慢总结。

【STD Code】

//本代码为COCI官方题解
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>

using namespace std;

const int MAXN = 26;
const int MAXNUM = 100100;
const int MOD = 1000000007;

enum {ROOT, LEFT, RIGHT};
typedef long long llint;

struct node {
  int x, y, z;
  llint dp[MAXNUM];
  vector< node* > children;

  node() {}
  node(int _x, int _y, int _z) {
    x = _x, y = _y, z = _z;
    memset(dp, -1, sizeof dp);
  }

  llint solve(int from = 0) {
    llint &ret = dp[from];
    if (ret != -1)
      return ret;
    ret = 0;

    if (z == ROOT) {
      for (int from = x; from <= y; ++from)
        ret = (ret + solve_for(from)) % MOD;
    }
    if (z == LEFT) {
      if (from > y)
        return ret;
      if (from < y)
        ret = solve(from + 1);
      ret = (ret + solve_for(from)) % MOD;
    }
    if (z == RIGHT) {
      if (from < x)
        return ret;
      if (from > x)
        ret = solve(from - 1);
      ret = (ret + solve_for(from)) % MOD;
    }

    return ret;
  }

  inline llint solve_for(int from) {
    llint ret = 1;
    for (vector< node* >::iterator it = children.begin(); it != children.end(); ++it)
      ret = (ret * (*it)->solve(from)) % MOD;
    return ret;
  }

} nodes[MAXN];

int main(void) {
  int n;
  scanf("%d", &n);

  for (int i = 0; i < n; ++i) {
    char xi[10], yi[10];
    scanf("%s %s", xi, yi);
    int x = atoi(xi);
    int y = atoi(yi);
    int z;
    if (x && y)
      z = ROOT;
    else if (y) {
      z = LEFT;
      nodes[xi[0] - ‘a‘].children.push_back(nodes + i);
    } else {
      z = RIGHT;
      nodes[yi[0] - ‘a‘].children.push_back(nodes + i);
    }
    nodes[i] = node(x, y, z);
  }

  llint ans = 1;
  for (int i = 0; i < n; ++i)
    if (nodes[i].z == ROOT)
      ans = (ans * nodes[i].solve()) % MOD;

  printf("%lld\n", ans);
  return 0;
}

【International Edition】

Mirko has written the following function:

C++:
int fun() { 
 int ret = 0; 
 for (int a = X1; a <= Y1; ++a) 
 for (int b = X2; b <= Y2; ++b) 
 ... 
 for (int <N-th> = XN; <N-th> <= YN; ++<N-th>) 
 ret = (ret + 1) % 1000000007; 
 return ret; 
}

Pascal:
function fun: longint; 
var 
 ret: longint; 
 a, b, ... , y, z: longint; 
begin 
 ret := 0; 
 for a := X1 to Y1 do 
 for b := X2 to Y2 do 
 ... 
 for <N-th> := XN to YN do 
 ret := (ret + 1) mod 1000000007; 
 fun := ret; 
end;

<N-th> denotes the Nth lowercase letter of the English alphabet. Each Xi and Yi denotes either a 
positive integer less than or equal to 100 000 or a name of a variable that some outer loop iterates over. 
For example, X3 can be either a, b, or an integer literal. At least one of Xi and Yi will be an integer 
literal (i.e. not a variable name) for every i. 
Compute the return value of the function.

INPUT

The first line of input contains the positive integer N (1 ≤ N ≤ 26). 
For the next N lines, the i
th line contains Xi and Yi, separated with a space. If Xi and Yi are both 
integer literals, then Xi ≤ Yi.

OUTPUT

The first and only line of output must contain the return value of the function.

第六题:披萨店(pizza)[raspored]

【题目描述】

Mirko的披萨店在镇上很受欢迎,每个人都把披萨作为午餐。Mirko提供外送服务,他的送货速度非常快,所以送货的时间可以忽略不计。镇上每个人都有自己最喜欢的口味,所以,Mirko给每个人做的披萨需要不同的时间。他只有一个小烤炉,每次只能烤一个披萨。如果他给某个人的披萨早于那个人的午餐时间k个时间单位,那么他可以收到k单位的小费,反之,如果晚于客户的午餐时间k个时间单位,那么他将损失k单位的钱。所以,Mirko需要提前安排好每个披萨制作的次序,以保证他的小费尽量多。每个客户的午餐时间是确定的,他的披萨需要花多少时间做好也是确定的。但是,可能客户会有所改变,一旦改变,那么mirko可能需要调整他的计划。Mirko从时刻0开始制作披萨。

【输入】

第一行包含两个正整数N和C,表示镇上的居民数和改变要求的次数。

接下来N行,每行包含两个正整数Li表示居民i的午餐时间,Ti表示居民i的披萨制作好需要的时间。

接下来有C行,每行包含3个正整数:R表示居民的序号,L表示该居民新的午餐时间,T表示该居民的新口味披萨需要制作的时间。

【输出】

第一行输出包含未发生改变时,Mirko能获得的最多的小费。接下来C行,每行表示发生了改变后,Mirko能获得的最多的小费。

【样例数据】


输入样例1:

3 2

10 2

6 5

4 3

1 6 1

3 0 10


输入样例2:

4 2

3 2

0 3

4 3

4 1

3 0 4

1 4 5


输入样例3:

6 7

17 5

26 4

5 5

12 4

8 1

18 2

3 31 3

4 11 5

4 19 3

5 23 2

6 15 1

5 19 1

3 10 4


输出样例1:

3

2

-11


输出样例2:

-8

-13

-18


输出样例3:

27

59

56

69

78

81

82

58

【数据规模】

1<=N,C<=200000,

0<=Li,L<=100000

1<=Ti,T<=100000,

1<=R<=N

【简单题解】

模型转化后可以发现T是无用的,只需要按照时间递增的顺序执行任务(贪心的经典模型),然后用线段树维护这个递增序的和就行了

【STD Code】

//本代码为官方题解
#include <cstdio>
#include <cstring>

#include <vector>
#include <algorithm>

using namespace std;

typedef long long llint;

#define MAX 200005

int N, Q;
int f[ MAX ];
int T[ 2 * MAX ];
int D[ 2 * MAX ];
int I[ 2 * MAX ];

llint SolT, SolD;
vector< pair< int, int > > v;

struct logaritamska {
  llint t[ 2 * MAX ];

  void update( int x, int v ) {
    for( int i = x + 1; i < 2 * MAX; i += i&-i ) t[i] += v;
  }

  llint query( int x, int y ) {
    if( x > y ) return 0;
    llint ret = 0;
    for( int i = y + 1; i; i -= i&-i ) ret += t[i];
    for( int i = x;     i; i -= i&-i ) ret -= t[i];
    return ret;
  }
} p, s;

int pos( int idx ) {
  return lower_bound( v.begin(), v.end(), make_pair( -T[idx], idx ) ) - v.begin();
}

void fix( int cpos, int idx, int sgn ) {
  SolT += sgn * llint( p.query( 0, cpos - 1 ) + 1 ) * T[idx];
  SolT += sgn * s.query( cpos + 1, N + Q - 1 );
  SolD += sgn * D[idx];

  p.update( cpos, sgn );
  s.update( cpos, sgn * T[idx] );
}

int main( void )
{
  scanf( "%d%d", &N, &Q );

  for( int i = 0; i < N; ++i ) {
    scanf( "%d%d", D+i, T+i );
    v.push_back( make_pair( -T[i], i ) );
  }

  for( int i = N; i < N+Q; ++i ) {
    scanf( "%d%d%d", I+i, D+i, T+i ); --I[i];
    v.push_back( make_pair( -T[i], i ) );
  }

  sort( v.begin(), v.end() );

  for( int i = 0; i < N; ++i ) {
    fix( pos( i ), i, +1 );
    f[i] = i;
  }

  printf( "%lld\n", SolD - SolT );

  for( int i = N; i < N+Q; ++i ) {
    fix( pos( f[I[i]] ), f[I[i]], -1 );
    fix( pos( i ), i, +1 );
    f[I[i]] = i;

    printf( "%lld\n", SolD - SolT );
  }

  return 0;
}

【International Edition】

Mirko’s pizza place is the best one in town. It is so good that all town residents eat pizza for lunch every day. Mirko’s delivery service is so fast that the delivery time is negligible. The problem is baking the pizzas, since all residents have their own favourite topping combination, so baking pizzas for two different residents doesn’t always take the same amount of time. Mirko only has one small baking oven with a capacity of a single pizza at a time, so good scheduling is extremely important and must be 
determined before the day starts. 
For each of the N town residents (denoted by numbers from 1 to N) we know the baking duration for their favourite pizza (Ti), as well as the moment in the day when they plan on having lunch (Li). If a resident receives their pizza K moments before the planned lunch time, Mirko is rewarded with a tip of K kunas1. On the other hand, if the pizza is delivered K moments late (after the planned lunch time), Mirko must pay the resident K kunas (because of his timely delivery insurance policy). If the pizza is 
delivered precisely on time, Mirko won’t get a tip, but he doesn’t have to pay anything either. 
Mirko would like to know the maximum total tip (including all insurance payouts as negative tips) that can be earned in a day if pizzas are baked in an optimal order. Notice that Mirko can earn a negative total tip (if he has to pay out more insurance than the amount of tips he receives). 
Since residents sometimes change their favourite pizza toppings, as well as their preferred lunch time, Mirko’s schedule must be adapted in order to keep earning optimal tip amounts. Write a program to compute the maximum total tip for the beginning requirements, as well as after each change. 
Note: In this town, the day starts at the moment t = 0 and lasts much longer than the time needed to 
bake pizzas for all residents. The schedule, including the adaptations, must be determined before the 
day starts.

INPUT

The first line of input contains two positive integers N and C, the number of residents and the number 
of pizza requirement changes, respectively. 
Each of the next N lines contains two positive integers: Li
, the moment when resident i plans on 
having lunch, and Ti
, the time needed to bake the pizza for resident i. 
Each of the next C lines contains three positive integers: R (the index of a resident), L (the new 
moment when resident R plans on having lunch), and T (the time needed to bake resident R’s new 
favourite pizza).

Constraints:

1 ≤ N, C ≤ 200 000, 
0 ≤ Li
, L ≤ 100 000, 
1 ≤ Ti
, T ≤ 100 000, 
1 ≤ R ≤ N.

OUTPUT

The first line of output must contain the maximum total tip for the beginning requirements of the 
residents. 
For each of the C changes, the output must contain an additional line of output containing the new 
maximum total tip value after the change.

SCORING

In test cases worth 50% of points, the following constraint holds: 1 ≤ Ti
, T ≤ 1000.

官方题解

COCI 2011/2012 Task NAJBOLJIH 5-考试得分
Round 2, November 19th, 2011 Author: Nikola Dmitrovi?

It is possible to solve this task in various ways. Expect for the most obvious solution where one looks for the 5 wanted numbers with 5 nested loops, we could just search for the 3 numbers with minimum sum and use 3 nested loops, which simplifies the code.
min=total; //sum of all numbers
for i=1 to 6 do
for j=i+1 to 7 do
for k=j+1 to 8 do
if score[i]+score[j]+score[k] < min tada begin
min:=score[i]+score[j]+score[k];
first:=i;
second:=j;
third:=k;
end;
print (total-min);
for i=1 to 8 do
if (i != prvi) and (i != drugi) and (i != treci) then print (i);
Required skills: nested loops
Category: ad hoc

COCI 2011/2012 Task OKRET-死胡同
Round 2, November 19th, 2011 Author: Adrian Satja Kurdija

There are dead-ends inside the given city if and only if there are road surface cells that are adjacent to only one other road surface cell.
Let’s prove this. If there is a road surface cell (let’s call it A) that has only one neighbor (B), then by moving from B to A we get stuck in A, i.e. our only way out is by a 180 degrees turn, which means that dead-end exists.
If there is no such cell, than we can exit every cell using some direction other than the one by which we came in. Let’s start at some road surface cell using any direction and proceed in the following matter: leave the cell we are currently in by using direction other than the one by which we came in. Since there are finite number of free cells, we will sooner or later enter some cell which we already visited. When this happens, one of these two statements are true: either we returned to the starting point, or we can return to the starting point using the same path. In both cases it’s possible to get back to the starting point, which concludes our proof.
Described solution is very easily implemented: for each road surface cell count the number of free cells.
Required skills: matrices manipulation
Category: ad hoc

COCI 2011/2012 Task ZADA?A-最大公约数
Round 2, November 19th, 2011 Author: Ivan Katani?

Greatest common divisor of two integers can be defined as the product of their common prime factors, as following:
A = p1a1 * p2a2 * … * pnan B = p1b1 * p2b2 * … * pnbn
GCD( A, B ) = p1min(a1,b1) * p2min(a2,b2) * … * pnmin(an,bn)
where p1..pn are the prime factors and a1..an, b1..bn are corresponding exponents.
We can get the factorization of large numbers A and B by factorizing every of their given factors and summing the prime number exponents over some prime in all factorizations. Next step is computing the GCD using the expression given above. For details check out the attached code.
Alternative solution would be to find GCD of all pairs of numbers Ai, Bj and it to the result (multiply), and divide the numbers Ai, Bj with the same number to prevent adding it to the result several times (in the next iterations).
Required skills: factorization, prime numbers
Category: number theory

COCI 2011/2012 Task KOMPI?I-数对
Round 2, November 19th, 2011 Author: Adrian Satja Kurdija

First thing to notice is that for each of the input values only set of it’s digits is of importance. We are not interested in order in which digits appear or repetition of digits. Therefore, each value can be represented with sequence of 10 binary digits - 1 if that digit is present, and 0 if it isn’t.
There are at most 210 = 1024 different sequences. For each sequence, we can easily calculate how many input values yield exactly that sequence, and store these results into some array.
For each pair of sequences, it’s easy to tell if they share some digit - they do if there is a position at which both sequences have ones. If they don’t share a digit, there are no pals here. If they do, than we can form a pair of pals by choosing any value that yields the first sequence, and any value that yields the second sequence. Total number of such pairs is:
number_of_values[ sequence1 ] * number_of_values[ sequence2 ].
Finally, we must count the number of pals that have the same sequence:
number_of_values[sequence] * (number_of_values[sequence] - 1) / 2
We must go through every possible pair of sequences, so complexity is O(10242).
Required skills: binary number system
Category: ad hoc

COCI 2011/2012 Task ZADA?A-N-th
Round 2, November 19th , 2011 Author: Ivan Katani?

Greatest common divisor of two integers can be defined as the product of their common prime factors, as following:
A = p1^a1 * p2^a2 * … * pn^an
B = p1^b1 * p2^b2 * … * pn^bn
GCD( A, B ) = p1^min(a1,b1) * p2^min(a2,b2) * … * pn^min(an,bn)
where p1..pn are the prime factors and a1..an, b1..bn are corresponding exponents.
We can get the factorization of large numbers A and B by factorizing every of their given factors and summing the prime number exponents over some prime in all factorizations. Next step is computing the GCD using the expression given above. For details check out the attached code.
Alternative solution would be to find GCD of all pairs of numbers Ai, Bj and it to the result (multiply), and divide the numbers A, B with the
same number to prevent adding it to the result several times (in the next iterations).
Required skills: factorization, prime numbers
Category: number theory

COCI 2011/2012 Task FUNKCIJA-比萨店
Round 2, November 19th , 2011 Author: Goran Gaši?

First observation we can make is that loops actually represent a system of inequalities:
X1 ≤ a ≤ Y1
X2 ≤ b ≤ Y2

XN ≤ <N-to> ≤ YN
Solution to our problems is the number of integer solutions of the given system of inequalities modulo 1000000007.
Lets build a graph with N nodes, each node representing one inequality. From a node which represents inequality of var1 we’ll put an edge towards node of var2 if upper or lower bound of var2 is equal to the same-kind bound of var1.
This graph is disjunct union of directed rooted trees. Since variables in different trees are independent of each other, the number of solutions for inequality system is equal to the product of number of solutions for each of the trees. Let us demonstrate how to calculate the solution for
only one tree.
Let f(root) is equal to the number of solutions of the tree rooted at root. Let g(node, number) equal to the number of solutions of a subtree rooted at node, if variable bound for that node inequality is equal to number. We’ll now make the following claims

for inequality with variable lower bound (it is analog in the case of 2 variable upper bound). This algoritm has complexity of O(NM ), where M is a limit on the upper bound, which is good enough for 70% of the points. Further, we can notice that following holds (for the variable lower bound case - as before it is analog with variable upper bound): points. Further, we can notice that following holds (for the variable lower bound case - as before it is analog with variable upper bound):

Using this observation, complexity becomes O(NM) and this wins 100% points.
Required skills: dynamic programming
Category: dynamic programming, graph theory

Time: 2017-03-18

时间: 2024-10-07 10:55:01

[SinGuLaRiTy] COCI 2011~2012 #2的相关文章

2011—2012学年度上学期单元测试 高一地理试题

一.选择题:本卷共25小题,每小题2分,共50分,每小题只有一个选项最符合题意. 读下面景观图片,回答1-2题. 1.甲图景观的形成突出反映了                                                                                         ( ) A.地壳的水平运动                           B.地壳的垂直运动 C.强烈的侵蚀作用                               

VRay 2.0 SP1 2.10.01 for 3ds max 9/2008/2009/2010/2011/2012 32/64位 顶渲简体中文版+英文版[中国室内设计论坛-室内人]

VRay 2.0 SP1 2.10.01 for 3ds max 9/2008/2009/2010/2011/2012 32/64位 顶渲简体中文版+英文版[中国室内设计论坛-室内人] 对最新版本的V-Ray2.0 SP1的所有版本,重新进行了一次彻底的汉化,继以前版本的彻底.稳定之处特点外,还对所发生的Bug进行了彻底排查,能正常支持V-Ray RT.分布渲染.材质烘焙.渲染元素等V-Ray全部功能.顶渲简体中文版,还剔除了原程序中用于二次开的SDK包,正常用户不需要此开发包,这使程序更加紧凑

[SinGuLaRiTy] COCI 2016~2017 #5

[SinGuLaRiTy-1008] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 测试题目 对于所有的题目:Time Limit:1s  |  Memory:256 MB 第一题:银行账户(account)[parato] [题目描述] 大家都知道28定律吧,据说世界上20%的人拥有80%的财富.现在你对一家银行的账户进行检测,看是否符合28定律,或者有更强的定律.比如说,10%的人拥有85%的财富.更准确的描述是:对N个银行账户进行

ACM ICPC 2011–2012, NEERC, Northern Subregional Contest J. John’s Inversions(合并排序求逆序数对数)

题目链接:http://codeforces.com/gym/100609/attachments 题目大意:有n张牌,每张牌有红色和蓝色两面,两面分别写了一些数字,同种颜色的任意两个数字若排在前面的数字比排在后面的数字大就叫做一对逆序数.求怎样排序得到的逆序数对最少. 解题思路:其中一种颜色的数字是顺序且这种颜色数字相同时对应的另一种颜色的数字是顺序时得到的逆序数对数最少.难点在于求逆序数对数.因为数量很大O(n^2)复杂度不能满足,这里根据合并排序的原理求解每个数字前面有多少个比它大的数字,

bzoj3188 [Coci 2011]Upit(分块)

Time Limit: 10 Sec  Memory Limit: 128 MB Description 你需要维护一个序列,支持以下4种操作.一,将区间(u,v)的数覆盖为C:二,将区间(u,v)的数依次加上一个以C为首项.C为公差的等差数列:三,将数C插入第i个位置:四,查询区间(u,v)的数的和.序列最初有n个数,一共会有Q次操作.保证结果在longlong范围内. Sample Input 5 5 1 2 3 4 5 1 5 5 0 4 4 5 4 5 5 2 1 5 1 4 1 5 S

NKOI 1363 (基础二分)

[COCI 2011/2012 CONTEST #5-2]砍树 Time Limit:10000MS  Memory Limit:32000KTotal Submit:49 Accepted:26 Case Time Limit:1000MS Description N棵树,每棵都有一个整数高度.有一个木头的总需要量M. 现在确定一个最大的统一的砍树高度H,如果某棵树的高度大于H,则高出的部分被砍下.使得所有被砍下的木材长度之和达到M(允许稍超过M). 例如,有4棵树,高度分别是20 15 10

【vijos】1791 骑士的旅行(特殊的技巧)

https://vijos.org/p/1791 暴力的话只想到bfs,然后估计是状态超了才得20分. 噗,为啥暴力就不能想得简单点QAQ.....这种思想很好啊. 这一题我看了题解后不得不说我竟然没想到.. 为啥要bfs..这种找路径的依赖前边状态的不需要bfs啊! 因为bfs是无限拓展的,状态很大,本题又是8种决策,状态达到8^n啊....sad.. 我们可以这样想,因为状态是向前走的,而且当前状态只依赖于前一个状态,那么我们可以用dp思想啊..直接枚举当前状态然后看是否根据上一状态到达,标

TOJ4505: KOSARE

TOJ4505: KOSARE  Time Limit(Common/Java):10000MS/30000MS     Memory Limit:65536KByteTotal Submit: 11            Accepted:3 Description Mirko found N boxes with various forgotten toys at his attic. There are M different toys, numbered 1 through M, but

SOS问题

SOS问题 模板 //iterative version for(int mask = 0; mask < (1<<N); ++mask){ dp[mask][-1] = A[mask]; //handle base case separately (leaf states) for(int i = 0;i < N; ++i){ if(mask & (1<<i)) dp[mask][i] = dp[mask][i-1] + dp[mask^(1<<i