Codeforces 992 (Div 2)

B. Nastya Studies Informatics

Today on Informatics class Nastya learned about GCD and LCM (see links below). Nastya is very intelligent, so she solved all the tasks momentarily and now suggests you to solve one of them as well.

We define a pair of integers (a, b) good, if GCD(a, b) = x and LCM(a, b) = y, where GCD(a, b) denotes the greatest common divisor of a and b, and LCM(a, b) denotes the least common multiple of a and b.

You are given two integers x and y. You are to find the number of good pairs of integers (a, b) such that l ≤ a, b ≤ r. Note that pairs (a, b) and (b, a) are considered different if a ≠ b.

Input

The only line contains four integers l, r, x, y (1 ≤ l ≤ r ≤ 109, 1 ≤ x ≤ y ≤ 109).

Output

In the only line print the only integer — the answer for the problem.

给出x, y, l, r问有多少对无需数对(a, b) 满足 l <= a, b <= r 且gcd(a, b) = x lcm(a, b) = y

首先有一个性质 对于满足 gcd(a, b) = x lcm(a, b) = y的 a, b, x, y有 a * b = x * y 因为gcd(a, b) = x 所以可以设 a = k1x, b = k2x

就有 k1x * k2x = x y -> k1xk2 = y 其中k1xk2都是y的因素,所以只需要通过sqrt(y)的复杂度枚举y的因子来确定k1x,代入后求得k2并验证是否合法

注意上面的式子 y 不能再除 x变为 k1k2 = y / x 因为这里的/是整除,进行后不一定相等

/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
    int f = 0, ch = 0; x = 0;
    for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
    for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
    if(f) x = -x;
}
inline ll gcd(ll a, ll b){ return b ? gcd(b, a % b) : a; }
int main(){
    ll x, y, l, r; 
    read(l), read(r), read(x), read(y);
    ll now = y, s = (ll) sqrt(now), ans = 0;
    for(ll i = x; i <= s * x; i += x) if(now % i == 0){
        if(i < l || (now / i) * x > r) continue;
        if(i > r || (now / i) * x < l) continue;
        if(gcd(i, (now / i) * x) != x) continue;
        if(i > (now / i) * x) break;
        if(i * i / x == now) ans += 1; else ans += 2;
    }
    cout << ans;
    return 0;
}
萌萌哒的代码>.<

C. Nastya and a Wardrobe

Nastya received a gift on New Year — a magic wardrobe. It is magic because in the end of each month the number of dresses in it doubles (i.e. the number of dresses becomes twice as large as it is in the beginning of the month).

Unfortunately, right after the doubling the wardrobe eats one of the dresses (if any) with the 50% probability. It happens every month except the last one in the year.

Nastya owns x dresses now, so she became interested in the expected number of dresses she will have in one year. Nastya lives in Byteland, so the year lasts for k + 1 months.

Nastya is really busy, so she wants you to solve this problem. You are the programmer, after all. Also, you should find the answer modulo 109 + 7, because it is easy to see that it is always integer.

Input

The only line contains two integers x and k (0 ≤ x, k ≤ 1018), where x is the initial number of dresses and k + 1 is the number of months in a year in Byteland.

Output

In the only line print a single integer — the expected number of dresses Nastya will own one year later modulo 109 + 7.

给你x和k,一共要进行k+1次操作,对于前k天,x 有 50%几率变成 2x,有50%几率变成 2x - 1,对于最后一天 x 变成 2x,问k + 1天之后x期望是多少

首先对于前k天的式子显然有设fi表示第i天后的期望 f[i] = (f[i-1] * 2 + f[i-1] * 2 - 1) / 2 -> f[i] = 2 * f[i-1] - 0.5

考虑这个式子做k次,发现2乘了k次,对于每一次出现的0.5,第i次的0.5 乘上了 2^k-i次, 所以所有0.5有关的项的和是2 ^ k - 1 - 0.5

算上最后一次答案就是 2 * ( 2 ^ k * x - 2 ^ (k - 1)  + 0.5) ,注意要特判 k = 0 和 n = 0 的情况不需要计算前面的部分

/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define P (1000000007)
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
    int f = 0, ch = 0; x = 0;
    for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
    for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
    if(f) x = -x;
}
inline ll Pow(ll a, ll b){
    ll ans = 1;
    for(; b; b >>= 1, a = a * a % P)
        if(b & 1) ans = ans * a % P;
    return ans;
}
int main(){
    ll x, k; read(x), read(k); 
    if(!k || !x) cout << 2ll * (x % P) % P;
    else x %= P, cout << (2ll * (Pow(2ll, k) * x % P - Pow(2ll, k - 1) + P) % P + 1ll) % P; 
    return 0;
}
萌萌哒的代码>.<

D. Nastya and a Game

Nastya received one more array on her birthday, this array can be used to play a traditional Byteland game on it. However, to play the game the players should first select such a subsegment of the array that , where p is the product of all integers on the given array, s is their sum, and k is a given constant for all subsegments.

Nastya wonders how many subsegments of the array fit the described conditions. A subsegment of an array is several consecutive integers of the array.

Input

The first line contains two integers n and k (1 ≤ n ≤ 2·105, 1 ≤ k ≤ 105), where n is the length of the array and k is the constant described above.

The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 108) — the elements of the array.

Output

In the only line print the number of subsegments such that the ratio between the product and the sum on them is equal to k.

给你一个序列,问你这个序列中存在多少个子序列满足这个子序列的积 = k倍的这个子序列的和

观察发现,如果说这个序列中所有元素都 > 1,那么枚举左端点,右端点距离左端点> 30时,就再也不可能会满足性质了

但是有1的存在,考虑把1"缩"起来, 观察发现只有k = 1的时候存在单独一个1满足条件,并且除此之外1要出现必须要有至少两个非1元素

假设存在元素x + p个1的子序列 (p >  0),那么他们的和是 x + p, 积是x,因为 k > 1且是整数那么显然有 k(x + p) > x,所以1要出现必须要有至少两个非1元素

所以将序列中所有1移去,枚举非1元素,考虑枚举到一段[l, r],l左边能选的1有L个,r左边能选的1有R个,如果积/k - 和 > 0 且 <= L + R,那么就有若干个子序列合法,简单计算即可

/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
    int f = 0, ch = 0; x = 0;
    for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
    for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
    if(f) x = -x;
}
#define N (500005)
#define int ll
int s[N], a[N], v[N], num, n, k, ans;
main(){
    read(n), read(k);
    if(k == 1) ans += n;
    for(int i = 1; i <= n; i++) read(a[i]), s[i] = s[i-1] + a[i];
    for(int i = 1; i <= n; i++) if(a[i] > 1) v[++num] = i; 
    v[num+1] = n + 1;
    for(int i = 1; i <= num; i++){
        int x = v[i], now = a[x];
        for(int j = i + 1; j <= num; j++){
            int y = v[j]; now *= a[y];
            if(now > (ll)(1e12)) break;
            if(now % k != 0) continue;
            int l = v[i] - v[i-1] - 1, r = v[j+1] - v[j] - 1;
            int det = now / k - s[y] + s[x-1];
            if(det >= 0 && det <= l + r){
                int sl = Min(l, det), dl = Max(0, det - r);
                ans += (sl - dl + 1);
            }
        }        
    }
    cout << ans << endl;
    return 0;
}
萌萌哒的代码>.<

E. Nastya and King-Shamans

Nastya likes reading and even spends whole days in a library sometimes. Today she found a chronicle of Byteland in the library, and it stated that there lived shamans long time ago. It is known that at every moment there was exactly one shaman in Byteland, and there were n shamans in total enumerated with integers from 1 to n in the order they lived. Also, each shaman had a magic power which can now be expressed as an integer.

The chronicle includes a list of powers of the n shamans. Also, some shamans can be king-shamans, if they gathered all the power of their predecessors, i.e. their power is exactly the sum of powers of all previous shamans. Nastya is interested in whether there was at least one king-shaman in Byteland.

Unfortunately many of the powers are unreadable in the list, so Nastya is doing the following:

  • Initially she supposes some power for each shaman.
  • After that she changes the power of some shaman q times (the shamans can differ) and after that wants to check if there is at least one king-shaman in the list. If yes, she wants to know the index of any king-shaman.

Unfortunately the list is too large and Nastya wants you to help her.

Input

The first line contains two integers n and q (1 ≤ n, q ≤ 2·105).

The second line contains n integers a1, ..., an (0 ≤ ai ≤ 109), where ai is the magic power of the i-th shaman.

After that q lines follow, the i-th of them contains two integers pi and xi (1 ≤ pi ≤ n, 0 ≤ xi ≤ 109) that mean that the new power of the pi-th shaman is xi.

Output

Print q lines, the i-th of them should contain  - 1, if after the i-th change there are no shaman-kings, and otherwise a single integer j, where j is an index of some king-shaman after the i-th change.

If there are multiple king-shamans after each change, print the index of any of them.

给你一个序列,进行q次操作,每次操作将一个数变为给定的一个数,每次操作完之后让你找出一个x满足  a[x]  = a[(x - 1)] 的前缀和

vp的时候写了一个nsqrt(nlogn)的做法,奈何算法不优,常数太大,20w的只跑过去了两三个,但还是先把这个做法给糊了

考虑每个位置对他前一个的前缀和作差记为s[i],那么s[i]表示的是如果要让这个点合法他还需改变多少,先让当s[i]为0的时候i就是一个答案

然后考虑对序列分块,块内排序,那么每一次修改就是对其所在的块改掉原数组位置在他后面的点和自己,对后面的块打标记,然后对自己所在的块二路归并保证有序

对于查询操作,就枚举所有的块,块内二分,判断是否有0,找到0后输出答案即可,如果将每一个块的大小调整为sqrt(nlogn)那么修改是sqrt(nlogn),查询是n/sqrt(nlogn) *  log(sqrt(nlogn)) = sqrt(nlogn)

/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
    int f = 0, ch = 0; x = 0;
    for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
    for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
    if(f) x = -x;
}
#define N (300005)
struct Node{ int x, id; } s[N];
int a[N], b[N], be[N], st[N], en[N], n, q;
inline bool cmp(const Node &A, const Node &B){ return A.x < B.x; }
int main(){
    read(n), read(q);
    for(int i = 1, x = 0; i <= n; i++) 
        read(a[i]), s[i].x = a[i] - x, s[i].id = i, x += a[i];
    int block = 750, num = 0;
    for(int i = 1; i <= n; i++) be[i] = (i - 1) / block + 1;
    for(int i = 1; i <= n; i++){
        if(be[i] != be[i-1]) st[be[i]] = i;
        if(be[i] != be[i+1]) en[be[i]] = i;
    }
    num = be[n];
    for(int i = 1; i <= num; i++)
        sort(s + st[i], s + en[i] + 1, cmp);
    while(q--){
        int x, y; read(x), read(y);
        int det = y - a[x], c = be[x], flag = 0; a[x] = y;
        for(int i = st[c]; i <=    en[c]; i++){
            if(s[i].id > x) s[i].x -= det;
            if(s[i].id == x) s[i].x += det;
        } 
        sort(s + st[c], s + en[c] + 1, cmp);
        for(int i = c + 1; i <= num; i++) b[i] -= det;
        for(int i = 1; i <= num; i++){
            int l = st[i], r = en[i], tmp = 0;
            while(l <= r){
                int mid = l + r >> 1;
                if(s[mid].x + b[i] <= 0) 
                    tmp = mid, l = mid + 1;
                else r = mid - 1;
            }
            if(tmp && s[tmp].x + b[i] == 0){
                printf("%d\n", s[tmp].id);
                flag = 1; break;
            }
        }
        if(!flag) printf("-1\n");    
    }
    return 0;
}
萌萌哒的代码>.<

猜你喜欢

转载自www.cnblogs.com/mangoyang/p/9207213.html
今日推荐