
I was impatient because I couldn't solve D, but if I think about it, I can solve it just by transforming the formula. Also, although I came up with the idea of the E problem, I could not analyze the amount of calculation. ** Keep in mind that analysis using harmonic series is important **.
Recently, the review has been neglected and various things have been delayed, so I would like to adjust the rhythm of the review.
Try up to $ [\ frac {n} {5}] $ times, conversion up to $ [\ frac {n} {2}] $, penalty goal up to $ [\ frac {n} {3} ] $ Times. Also, since $ N $ is 100 or less, you can search all. However, keep in mind that it is the number of conversions $ \ leqq $ the number of tries.
A.py
n=int(input())
ans=0
for i in range(n//5+1):
    for j in range(n//2+1):
        for k in range(n//3+1):
            ans+=(i*5+j*2+k*3==n and i>=j)
print(ans)
First, the treasure chest probabilities have nothing to do with the answer, so let's say $ p \ leqq q \ leqq r $.
At this time, mark a treasure chest and ** STAY or CHANGE **. When selecting STAY, ** STAY to the treasure chest with the highest probability is the maximum **, so the probability of getting a diamond is equal to the probability of having a diamond in the selected treasure chest $ r / (p + q + r) It's $. When selecting CHANGE, ** the maximum probability is to change from the treasure chest with the lowest probability **, so the probability of getting a diamond is equal to the probability of having a diamond in the unselected treasure chest $ (q + r) / ( p + q + r) $.
Therefore, the answer is $ max (r / (p + q + r), (q + r) / (p + q + r)) = (q + r) / (p + q + r) $.
B.py
p,q,r=sorted(list(map(int,input().split())))
print((q+r)/(p+q+r))
First, it's important to be a multiple of 10, so take $ mod \ 10 $ for each card. Also, by choosing one card, the value of $ mod \ 10 $ will change, and ** consider the DP that you can have with the maximum number of cards you can choose as the state. At this time, set DP as follows.
$ dp [i]: = $ (maximum number of sheets when the remainder is $ i $)
Also, the transition will be as follows when selecting the card $ A \ _j $.
In addition, ** the transition is not one-way **, so you need to update ** $ dp $ collectively ** when you select card $ A \ _j $. Therefore, each card $ A \ _j $ update must be saved in $ dp \ _sub $ and recorded in $ dp $ after the card $ A \ _j $ has been selected.
C.py
ans=0
n=int(input())
check=[0 for i in range(10)]
a=list(map(int,input().split()))
for i in a:
    check[i%10]+=1
dp=[0 for i in range(10)]
for i in range(10):
    for j in range(check[i]):
        dp_sub=[0]*10
        for k in range(10):
            if k==0:
                dp_sub[(i+k)%10]=dp[k]+1
            elif dp[k]!=0:
                dp_sub[(i+k)%10]=dp[k]+1
        for k in range(10):
            dp[k]=max(dp[k],dp_sub[k])
        #print(dp_sub)
#print(dp)
print(dp[0])
I thought about it for a while during and after the contest, but I didn't understand. If I had a head, I might have solved it.
It's hard to think of conspicuous rules and typical solutions, but since it's a ** problem of the relationship between prime numbers and powers **, I'll use ** Fermat's Little Theorem **. Fermat's little theorem is as follows.
When p is a prime number and a is a relatively prime integer with p, a^{p-1} = 1\ (mod \ p) \\
To show this, from the binomial theorem a^{p} = a\ (mod \ p)Just show.
First, if you substitute the value into Fermat's little theorem as it is, $ 2 ^ {p \ _ i-1} = 1 \ (mod \ p \ _ i) $… ① holds, so consider ** transforming this formula **. I will. Also, ** 2 and $ p \ _i $ must be relatively prime **, but this is only when $ p \ _i = 2 $, which holds for $ x = 2 $. Here, the value on the right side does not change when the power of both sides ** of ** ① is taken, but the value on the left side changes. In other words, if you take the $ t $ power of both sides of ①, $ 2 ^ {t (p \ _ i-1)} = 1 \ \ (mod \ p \ _i) $ holds. Also, what you want to find is when $ 2 ^ {t (p \ _ i-1)} = t (p \ _ i-1) \ \ (mod \ p \ _i) $. Therefore, if ** two sides are combined **, $ t (p \ _ i-1) = 1 \ \ (mod \ p \ _ i) $ is established. By transforming this, if $ t = p \ _i-1 $ is set from $ p \ _i-t = 1 \ \ (mod \ p \ _i) $, this is satisfied, and $ x = (p \ _ i-1) ) ^ 2 $ is less than $ 10 ^ {18} $, so it certainly meets the criteria in question.
From the above, the subject is satisfied by $ x = 2 $ when $ p \ _i = 2 $ and $ x = (p \ _ i-1) ^ 2 $ when $ p \ neq 2 $.
D.py
for i in range(int(input())):
    n=int(input())
    print(2 if n==2 else (n-1)**2)
I learned a lot because ** Computational complexity analysis by harmonic series ** was the first type of problem to solve an important problem. For the harmonic series, refer to this article.
First, find the sum of the values of $ A \ _i % A \ _j $ for any $ i, j $. In such a ** summation problem, it is good to pay attention to each value **, but it is difficult to leave it as it is, so consider ** paraphrase **. In other words, $ A \ _i % A \ _j = A \ _i-[\ frac {A \ _i} {A \ _ j}] \ times A \ _j $. At this time, $ A \ i $ is $ n \ sum {i = 1} ^ {n} A \ _i $, so it can be calculated by $ O (N) $, but $ [\ frac {A \ _i} {A \ _ j}] \ times A \ _ j $ is not easy to find.
Here, if you fix $ A \ _j $, there may be $ i $ that matches ** $ [\ frac {A \ _i} {A \ _j}] \ times A \ _j $ ** Because there is, let's fix $ A \ _j $ (because if $ \ because $ matches, ** can be calculated together ** in most cases). Also, when the values match and $ [\ frac {A \ _i} {A \ _j}] = k $, $ A \ _j \ times k \ leqq A \ _i <A \ j \ times (k +) 1) Since it becomes $, we will count it together with the image of ** frequency distribution **. At this time, if you arrange the sequence $ A $ in ascending order, you can ** find out how many numbers correspond to a certain $ k $ using a binary search **. Also. To improve the efficiency of calculation, the sum when fixed at a certain $ A \ j $ is saved in the dictionary, and if the same number appears, the number saved in the dictionary is used. Also, there are up to $ [\ frac {A \ _ {max}} {A \ j}] $ for each $ A \ j $, and each search costs $ O (\ log {n}) $. , The total complexity is $ O (\ sum \ _ {j = 1} ^ {n} [\ frac {A \ _ {max}} {A \ _ j}] \ log {n}) = O (A { max} \ log {n} \ sum \ _ {j = 1} ^ {n} [\ frac {1} {A \ _ j}]) $. Also, here from ** the concept of harmonic series ** (✳︎), $ O (\ sum \ _ {j = 1} ^ {n} [\ frac {1} {A \ _ j}]) = O (\ log Since {A {max}}) $, the total amount of calculation is $ O (A {max} \ log {n} \ log {A {max}}) $.
(✳︎)… ** I want to make it so that when I see the sum of fractions, I can reduce it to a harmonic series **!
E.py
n=int(input())
a=list(map(int,input().split()))
a.sort()
from bisect import bisect_left,bisect_right
ans=0
d=dict()
for i in range(n):
    if a[i] in d:
        ans+=d[a[i]]
        continue
    ans_sub=0
    j=i
    while j!=n:
        x=a[j]//a[i]
        b=bisect_left(a,(x+1)*a[i],lo=j)-1
        ans_sub+=(x*(b-j+1)*a[i])
        j=b+1
    d[a[i]]=ans_sub
    ans+=ans_sub
print(sum(a)*n-ans)
I have copied the code in this article. If it's a simple problem, you can use another library, but it's a difficult problem and you can't do the same, so I'll try to make a library of segment trees as soon as possible.
F.cc
//Debugging options:-fsanitize=undefined,address
//Compiler optimization
#pragma GCC optimize("Ofast")
//Include etc.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//macro
//for loop
//The argument is(Variables in the loop,Range of movement)Or(Variables in the loop,First number,Number of ends)、のどちらOr
//If there is no D, the loop variable is incremented by 1, and if it is with D, the loop variable is decremented by 1.
//FORA is a range for statement(If it's hard to use, erase it)
#define REP(i,n) for(ll i=0;i<ll(n);i++)
#define REPD(i,n) for(ll i=n-1;i>=0;i--)
#define FOR(i,a,b) for(ll i=a;i<=ll(b);i++)
#define FORD(i,a,b) for(ll i=a;i>=ll(b);i--)
#define FORA(i,I) for(const auto& i:I)
//x is a container such as vector
#define ALL(x) x.begin(),x.end() 
#define SIZE(x) ll(x.size()) 
//constant
#define MOD 1000000007 //10^9+7:Congruence law
#define MAXR 100000 //10^5:The largest range in the array
//Abbreviation
#define PB push_back //Insert
#define MP make_pair //pair constructor
#define F first //The first element of pair
#define S second //The second element of pair
/* RMQ:[0,n-1]Structure that manages the minimum value for each section
    set(i,x), build():Set the i-th element to x. Build a seg tree together. O(n)
    add(a,b,x):section[a,b)Add x to the element of. O(log(n))
    query(a,b):section[a,b)Get the smallest element in. O(log(n))
    find_rightest(a,b,x): [a,b)Find the rightmost position with elements less than or equal to x. O(log(n))
    find_leftest(a,b,x): [a,b)Find the leftmost position with elements less than or equal to x. O(log(n))
*/
template <typename T>
struct RMQ {
    const T INF = numeric_limits<T>::max();
    int n;
    vector<T> dat, lazy;
    RMQ(int n_) : n(), dat(n_ * 4, INF), lazy(n_ * 4, 0) {
        int x = 1;
        while (n_ > x) x *= 2;
        n = x;
    }
    void set(int i, T x) { dat[i + n - 1] = x; }
    void build() {
        for (int k = n - 2; k >= 0; k--) dat[k] = min(dat[2 * k + 1], dat[2 * k + 2]);
    }
    /* lazy eval */
    void eval(int k) {
        if (lazy[k] == 0) return;  //Exit if there is nothing to update
        if (k < n - 1) {           //If it is not a leaf, it propagates to the child
            lazy[k * 2 + 1] += lazy[k];
            lazy[k * 2 + 2] += lazy[k];
        }
        //Update yourself
        dat[k] += lazy[k];
        lazy[k] = 0;
    }
    void add(int a, int b, T x, int k, int l, int r) {
        eval(k);
        if (a <= l && r <= b) {  //When completely inside
            lazy[k] += x;
            eval(k);
        } else if (a < r && l < b) {                  //When some sections are covered
            add(a, b, x, k * 2 + 1, l, (l + r) / 2);  //Left child
            add(a, b, x, k * 2 + 2, (l + r) / 2, r);  //Right child
            dat[k] = min(dat[k * 2 + 1], dat[k * 2 + 2]);
        }
    }
    void add(int a, int b, T x) { add(a, b, x, 0, 0, n); }
    T query_sub(int a, int b, int k, int l, int r) {
        eval(k);
        if (r <= a || b <= l) {  //When completely outside
            return INF;
        } else if (a <= l && r <= b) {  //When completely inside
            return dat[k];
        } else {  //When some sections are covered
            T vl = query_sub(a, b, k * 2 + 1, l, (l + r) / 2);
            T vr = query_sub(a, b, k * 2 + 2, (l + r) / 2, r);
            return min(vl, vr);
        }
    }
    T query(int a, int b) { return query_sub(a, b, 0, 0, n); }
    T find_rightest(int a, int b, int x) { return find_rightest_sub(a, b, x, 0, 0, n); }  //If it does not exist a-1
    T find_leftest(int a, int b, int x) { return find_leftest_sub(a, b, x, 0, 0, n); }    //If it does not exist b
    T find_rightest_sub(int a, int b, int x, int k, int l, int r) {
        eval(k);
        if (dat[k] > x || r <= a || b <= l) {  //Your value is greater than x or[a,b)But[l,r)If it is out of the range of, return a-1
            return a - 1;
        } else if (k >= n - 1) {  //If you are a leaf, return that position
            return (k - (n - 1));
        } else {
            int vr = find_rightest_sub(a, b, x, 2 * k + 2, (l + r) / 2, r);
            if (vr != a - 1) {  //Look at the subtree on the right a-If other than 1, return
                return vr;
            } else {  //Look at the subtree on the left and return the value
                return find_rightest_sub(a, b, x, 2 * k + 1, l, (l + r) / 2);
            }
        }
    }
    T find_leftest_sub(int a, int b, int x, int k, int l, int r) {
        eval(k);
        if (dat[k] > x || r <= a || b <= l) {  //Your value is greater than x or[a,b)But[l,r)If it is out of the range of, return b
            return b;
        } else if (k >= n - 1) {  //If you are a leaf, return that position
            return (k - (n - 1));
        } else {
            int vl = find_leftest_sub(a, b, x, 2 * k + 1, l, (l + r) / 2);
            if (vl != b) {  //Look at the subtree on the left and return if it is other than b
                return vl;
            } else {  //Look at the subtree on the right and return the value
                return find_leftest_sub(a, b, x, 2 * k + 2, (l + r) / 2, r);
            }
        }
    }
    /* debug */
    inline T operator[](inta){returnquery(a,a+1); }
    void print() {
        for (int i = 0; i < n; ++i) {
            cout << (*this)[i];
            if (i != n) cout << ",";
        }
        cout << endl;
    }
};
signed main(){
    //Code for speeding up input
    //ios::sync_with_stdio(false);
    //cin.tie(nullptr);
    ll n;cin>>n;
    RMQ<ll> x(n);
    REP(i,n){
        ll y;cin>>y;
        x.set(i,y);
    }
    x.build();
    ll q;cin>>q;
    REP(i,q){
        ll k,l,r,c;cin>>k>>l>>r>>c;
        if(k==1){
            x.add(l-1,r,c);
        }else{
            cout<<x.query(l-1,r)<<endl;
        }
    }
    //x.print();
}
        Recommended Posts