Submission #715627

#TimeUsernameProblemLanguageResultExecution timeMemory
715627boris_mihovHorses (IOI15_horses)C++17
37 / 100
197 ms70880 KiB
#include "horses.h"
#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>

typedef long long llong;
const int MAXN = 500000 + 10;
const int MOD = 1e9 + 7;

struct Node
{
    __int128 ans;
    __int128 prodX;
    bool isANSbig;
    bool isXbig;

    inline friend Node operator + (Node left, Node right)
    {
        Node res;
        res.prodX = left.prodX * right.prodX;
        if (res.prodX >= 1LL * MOD * MOD)
        {
            res.isXbig = true;
            res.prodX %= 1LL * MOD * MOD;
        } else
        {
            res.isXbig = left.isXbig || right.isXbig;
        }
        
        if (left.isXbig || right.isANSbig || (left.ans < left.prodX * right.ans))
        {
            res.ans = left.prodX * right.ans;
            if (res.ans >= 1LL * MOD * MOD || left.isXbig || right.isANSbig)
            {
                res.isANSbig = true;
                res.ans %= 1LL * MOD * MOD; 
            }
        } else
        {
            res.ans = left.ans;
            res.isANSbig = left.isANSbig;
        }

        return res;
    }
};

int n;
int x[MAXN];
int y[MAXN];
struct SegmentTree
{
    Node tree[4 * MAXN];
    void build(int l, int r, int node)
    {
        if (l == r)
        {
            tree[node].prodX = x[l];
            tree[node].isXbig = false;
            tree[node].isANSbig = false;
            tree[node].ans = 1LL * x[l] * y[l];
            return;
        }

        int mid = (l + r) / 2;
        build(l, mid, 2*node);
        build(mid + 1, r, 2*node + 1);
        tree[node] = tree[2*node] + tree[2*node + 1];
    }

    void update(int l, int r, int node, int queryIdx, int queryVal, bool which)
    {
        if (l == r)
        {
            if (!which) x[l] = queryVal;
            else y[l] = queryVal;
            tree[node].ans = 1LL * x[l] * y[l];
            tree[node].prodX = x[l];
            return;
        }

        int mid = (l + r) / 2;
        if (queryIdx <= mid) update(l, mid, 2*node, queryIdx, queryVal, which);
        else update(mid + 1, r, 2*node + 1, queryIdx, queryVal, which);
        tree[node] = tree[2*node] + tree[2*node + 1];
    }

    inline int getANS()
    {
        return tree[1].ans % MOD;
    }

    void build()
    {
        build(1, n, 1);
    }

    void update(int idx, int val, bool which)
    {
        update(1, n, 1, idx, val, which);
    }
};

SegmentTree tree;
int init(int N, int X[], int Y[]) 
{
    n = N;
    for (int i = 1 ; i <= n ; ++i)
    {
        x[i] = X[i - 1];
        y[i] = Y[i - 1];
    }

    tree.build();
	return tree.getANS();
}

int updateX(int pos, int val) 
{
    pos++;
    tree.update(pos, val, false);
	return tree.getANS();
}

int updateY(int pos, int val) 
{
    pos++;
    tree.update(pos, val, true);
	return tree.getANS();
}

Compilation message (stderr)

horses.cpp: In member function 'int SegmentTree::getANS()':
horses.cpp:91:28: warning: conversion from '__int128' to 'int' may change value [-Wconversion]
   91 |         return tree[1].ans % MOD;
      |                ~~~~~~~~~~~~^~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...