2021 CCPC哈尔滨站

2021 CCPC哈尔滨站

B: Magical Subsequence

Given a sequence A1,A2,⋯,AnA1,A2,⋯,An. As for a subsequence Ab1,Ab2,⋯,Abm(1≤b1<b2<⋯<bm≤n)Ab1,Ab2,⋯,Abm(1≤b1<b2<⋯<bm≤n), we say it magical if and only if mm is even and Ab1+Ab2=Ab3+Ab4=⋯=Abm−1+AbmAb1+Ab2=Ab3+Ab4=⋯=Abm−1+Abm. Determine the maximum length among all magical subsequences of the given sequence.

Input

The first line contains one integer n(2≤n≤105)n(2≤n≤105), denoting the length of given sequence.

The second line contains nn integers A1,A2,⋯,An(1≤Ai≤100)A1,A2,⋯,An(1≤Ai≤100), denoting the given sequence.

Output

Output one line containing only one integer, denoting the answer.

Example

Input

Copy

11
3 1 4 1 5 9 2 6 5 3 5

Output

Copy

6

Note

One possible magical subsequence of length 6 is {A1=3,A5=5,A7=2,A8=6,A9=5,A10=3}{A1=3,A5=5,A7=2,A8=6,A9=5,A10=3}. Here 3+5=2+6=5+3=83+5=2+6=5+3=8.

题目描述:

给定一个长度为n的序列,如果对于子序列A(b1),A(b2),……,A(bm),当且仅当m为偶数且1<=b1<=b2<=…<=bm且A(b1)+A(b2)=A(b3)+A(b4)=….=A(bm-1)+A(bm)的时候他就是神奇的,求神奇子序列的最大长度

问题解析:

由于数据范围非常小,1<=Ai<=100,和的范围在2到200,所以可以直接暴力枚举和sum,对于某一个数x,如果sum-x可以取到,那么根据贪心的想法,这个点的位置我们是一定要取的,因为如果这个点不取的话,后续再来一个点可能会导致当前这个点没有办法取了,这是因为1<=b1<=b2<=b3<=…<=bm,所以用一个map记录一下出现的位置,一个pos表示已经取到了哪个位置。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define close ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)

void solved()
{
    int n;
    cin >> n;
    vector<int> input(n + 1, 0);
    for (int i = 1; i <= n; i++)
    {
        cin >> input[i];
    }
    int ans = 0;
    for (int i = 2; i <= 200; i++)
    {
        unordered_map<int, int> pre;
        int used = -1e18;
        int cnt = 0;
        for (int j = 1; j <= n; j++)
        {
            int now = input[j], other = i - input[j];
            if (other <= 0 || other > 100 || !pre.count(other))
            {
                pre[now] = j;
                continue;
            }
            else
            {
                if (j > used && pre[other] > used)
                {
                    cnt += 2;
                    used = j;
                }
                pre[now] = j;
            }
        }
        ans = max(ans, cnt);
    }
    cout << ans << endl;
}

signed main()
{
    close;
    solved();
    return 0;
}

D: Math master

Tang Keke is good at math. She knows how to simplify fractions very well. Even greater, she invented a simplifying method by herself!

The method is to choose some digits which appear in both the top and the bottom and erase them on both sides while keeping the fraction value unchanged. The digits are the same, so they can reduce each other. Sounds very logical, right?

The method may produce multiple simplified results and the one with the least top number is called the most simplified form. Keke prepared some fractions and is going to test if you can get the most simplified form.

Note that the chosen digits form a multiset, you can see the examples for more details.

Input

The first line contains an integer n(1≤n≤10)n(1≤n≤10), denoting the number of fractions.

Each of the next nn lines contains two integer p,q(0<p,q<263)p,q(0<p,q<263), denoting the fraction pqpq.

Output

For each fraction, output two integers x,yx,y in one line, indicating the most simplified form of the corresponding fraction is xyxy.

Notice: if there are some leading zeros after removal, you can ignore them and output the normal number. For example, if you get 007/123 finally, then you should output “7 123” instead of “007 123”.

Example

Input

Copy

4
163 326
326 163
1000 1000
2232 162936

Output

Copy

1 2
2 1
1 1
232 16936

Note

  • For the first and the second case, the erased digit multisets are both {3,6}{3,6}.
  • For the third case, the erased digit multiset is {0,0,0}{0,0,0}.
  • For the fourth case, the erased digit multiset is {2}{2}.

问题描述:

一共有n组数据,每组数据有一个分子p和一个分母q,在保持p/q的值不变的前提下,可以尽可能删除多的数字。且这种数字是分子和分母所共有的。

问题解析:

由于数据范围很大很大,所以我们需要用__int128,我们可以暴力枚举最后存下来的分子的哪个数字,留下的数字首先要是最大公因数的倍数,其次它不能是0,然后就可以算出分母,最后看一下分母是否满足条件

#include <bits/stdc++.h>
using namespace std;
typedef __int128 ll; 
#define endl '\n'
#define close ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
ll toNum(string s)
{
    ll ans = 0;
    for (auto i : s)
    {
        ans = ans * 10 + (i - '0');
    }
    return ans;
}

void solved()
{
    string s1, s2;
    cin >> s1 >> s2;
    int len1 = s1.length();
    int len2 = s2.length();

    ll p = toNum(s1);
    ll q = toNum(s2);

    vector<int> P(len1 + 1, 0);
    vector<int> Q(len2 + 1, 0);

    for (int i = 0; i < len1; i++)
    {
        P[i] = s1[i] - '0';
    }
    for (int i = 0; i < len2; i++)
    {
        Q[i] = s2[i] - '0';
    }

    for (int i = 1; i < (1LL << len1); i++)
    { 
        bitset<20> myBit(i);
        string now;
        vector<int> dis(10, 0);

        for (int j = 0; j < len1; j++)
        { 
            if (myBit[j])
            {
                now.push_back(s1[j]);
            }
            else
            {
                --dis[s1[j] - '0'];
            }
        }

        ll cntP = toNum(now);
        ll cntQ = cntP * q;

        if (cntQ % p != 0 || cntP == 0)
        {
            continue;
        }

        cntQ /= p;
        ll pre = cntQ;

        for (int j = len2 - 1; j >= 0; j--)
        {
            if (s2[j] - '0' == cntQ % 10)
            {
                cntQ /= 10;
            }
            else
            {
                ++dis[s2[j] - '0'];
            }
        }

        int flag = 1;
        for (int i = 0; i <= 9; i++)
        {
            if (dis[i])
            {
                flag = 0;
                break;
            }
        }

        if (flag && cntQ == 0 && cntP != 0 && pre != 0)
        {
            p = min(p, cntP);
            q = min(q, pre);
        }
    }

    cout << (long long)p << " " << (long long)q << endl;
}

int main()
{
    close;
    int T;
    cin >> T;
    while (T--)
    {
        solved();
    }
    return 0;
}


E: Power and Modulo

Given nn non-negative integers A1,A2,⋯,AnA1,A2,⋯,An. Determine if there is only one positive integer MM that ∀i∈{1,2,⋯,n},Ai=2i−1modM∀i∈{1,2,⋯,n},Ai=2i−1modM. If so, print the integer MM, or print “-1”.

Here, amodbamodb denotes the remainder of aa after division by bb, where a∈[0,b)a∈[0,b) holds. For example, 5mod2=15mod2=1, 9mod3=09mod3=0, 1mod2=11mod2=1.

Input

The first line contains one integer T(1≤T≤105)T(1≤T≤105), denoting the number of test cases.

For each test case:

The first line contains one integer n(1≤n≤105)n(1≤n≤105), denoting the number of given integers.

The second line contains nn integers A1,A2,⋯,An(0≤Ai≤109)A1,A2,⋯,An(0≤Ai≤109), denoting the given integers.

It is guaranteed that ∑n≤105∑n≤105 among all cases.

Output

For each test case:

Output one line containing one integer, denoting the answer.

Example

Input

Copy

3
5
1 2 4 1 2
5
1 2 4 8 16
5
1 2 4 0 1

Output

Copy

7
-1
-1

Note

  • For the first test case, M=7M=7.
  • For the second test case, MM can be any integer greater than 16, so output “-1” here.
  • For the third test case, no valid MM exists.

问题描述:

一共T组数据,每组数据有n个数,这n个数是2^(i-1) mod m 的值,如果有唯一确定的m,那么就输出m,如果没有这样的数就输出-1

问题解析:

首先第一个数是0的话需要特判,因为1 mod 1才是 0,那么这里特判就很简单了,直接判断输入的n个数是不是都是0,其次就看2Ai!=Ai+1的位置,因为当前这个值仅可能在Ai到2Ai的位置取到,然后就可以直接算出来这个答案是什么,最后判断一下就好了,如果没有找到这样的位置,说明m有无限个数字,只需要大于An就行

#include <bits/stdc++.h>
using namespace std;
#define int long long int
#define close ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
int qpow(int a, int b, int mod)
{
    int ans = 1;
    while (b)
    {
        if (b & 1)
            ans = ans * a % mod;
        b >>= 1;
        a = a * a % mod;
    }
    return ans % mod;
}
void solved()
{
    int n;
    cin >> n;
    vector<int> input(n + 1, 0);
    for (int i = 1; i <= n; i++)
    {
        cin >> input[i];
    }
    if (input[1] == 0)
    {
        int flag = 1;
        for (int i = 1; i <= n; i++)
        {
            if (input[i])
            {
                flag = 0;
                break;
            }
        }
        if (!flag)
        {
            cout << -1 << endl;
        }
        else
        {
            cout << 1 << endl;
        }
        return;
    }
    else
    {
        int loc = -1;
        for (int i = 1; i < n; i++)
        {
            if (input[i + 1] != input[i] * 2)
            {
                loc = i;
                break;
            }
        }
        if (loc == -1)
        {
            cout << -1 << endl;
            return;
        }
        else
        {
            int result = 2 * input[loc] - input[loc + 1];
            for (int i = 1; i <= n; i++)
            {
                if (qpow(2, i - 1, result) % result != input[i])
                {
                    cout << -1 << endl;
                    return;
                }
            }
            cout << result << endl;
        }
    }
}
signed main()
{
    close;
    int T;
    cin >> T;
    while (T--)
    {
        solved();
    }
    return 0;
}

G: Damaged Bicycle

Ring Ring Ring … The bell rang at half past six in the morning. After turning off the alarm, George went on to sleep again. When he woke up again, it was seven fifty and there were ten minutes left for class!

George immediately got up from bed, dressed, packed his backpack, brushed his teeth and washed his face. Then, he immediately rushed out of the dormitory and embarked on the road to the teaching building. On the way, he turned on his mobile phone to locate and saw several yellow shared bicycles nearby. Therefore, he headed to a bicycle and took out his mobile phone to scan the QR code on the bicycle. Unfortunately, the bicycle wasn’t unlocked, and a line of words “this bicycle is damaged and can’t be unlocked” was displayed on the screen.

Without riding a bicycle, he was late. What a bad day!

Indeed, some bicycles in the school are damaged, but their location will still be displayed on the app. George always rides faster than he walks, but considering that some bicycles are damaged, if George tries one by one, it may take a long time! In this regard, he has made some modeling, and hopes you can help him find the best strategy.

The campus can be modeled as a graph of nn vertices and mm bidirected edges, where the ii-th edge is wiwi meters long. George’s dormitory is located at vertex 11 and Guanghua Tower (the teaching building) is at vertex nn, so George has to go from vertex 11 to vertex nn to take classes. His walking speed is tt meters per second and his riding speed is rr meters per second. According to the bicycle sharing app, there are kk parked bicycles in the campus. The ii-th bicycle is located at vertex aiai, and of probability pi100pi100 to be damaged according to George’s experience. However, only when George arrives at vertex aiai and scans the QR code, can he determine whether the ii-th bicycle is damaged or not. As soon as a bicycle is confirmed to be undamaged, George will get on it immediately and will not get off until he reaches vertex nn.

Now George wants to save time to get to the classroom. So you, George’s roommate, should help him find an optimal strategy to minimize the mathematical expectation of the time cost on the way, and then output this value. Or you can let him continue sleeping if vertex nn is not reachable.

In this problem, you should only consider the time of walking and cycling, and you can assume that the other actions(scanning QR code, getting on, getting off, ⋯⋯) cost no time.

Input

The first line contains two integers t,r(1≤t≤r≤104)t,r(1≤t≤r≤104) — the speed of walking and the speed of riding, respectively.

The second line contains two integers n,m(1≤n,m≤105)n,m(1≤n,m≤105) — the number of vertices and the number of bidirected edges in the given graph.

Following mm lines each contains three integers ui,vi,wi(1≤ui,vi≤n,ui≠vi,1≤wi≤104)ui,vi,wi(1≤ui,vi≤n,ui≠vi,1≤wi≤104), denoting that vertices u,vu,v are connected by a wiwi-meter-long bidirected edge.

The next line contains a single integer k(0≤k≤18)k(0≤k≤18), denoting the number of bicycles in campus.

Following kk lines each contains two integers ai,pi(1≤ai≤n,0≤pi≤100)ai,pi(1≤ai≤n,0≤pi≤100), denoting the locations of the bicycles and the percentages of damage probabilities respectively.

It is guaranteed that no two bicycles are in the same vertex.

Output

If George cannot reach vertex nn, output one line containing one integer “-1”, or output one line containing one real number, denoting the minimum expectation of the time cost on the way.

As long as the relative or absolute error between your answer and the standard answer is within 10−610−6, your answer will be considered correct.

Examples

Input

Copy

3 15
4 3
1 2 600
1 3 300
2 4 900
1
3 50

Output

Copy

460.000000

Input

Copy

3 15
5 4
1 2 600
1 3 300
2 5 900
3 4 3
2
3 50
4 0

Output

Copy

220.600000

Input

Copy

3 15
5 4
1 2 600
1 3 300
4 5 900
3 2 300
2
3 50
4 0

Output

Copy

-1

Note

For the first test case, one possible strategy is:

  1. Go along the route 1→31→3 and try to ride the only bicycle in the campus.
  2. If the bicycle is damaged, go along the route 3→1→2→43→1→2→4 on foot, or go by bicycle.

Considering the time cost on the way:

  • If the bicycle is damaged, George should go along the route 1→3→1→2→41→3→1→2→4 on foot, whose total length is 2100 meters. So the time cost is 21003=70021003=700 seconds.
  • If the bicycle is undamaged, George should go along the route 1→31→3 on foot, whose total length is 300 meters, and then go along the route 3→1→2→43→1→2→4 by bicycle, whose total length is 1800 meters. So the time cost is 3003+180015=2203003+180015=220 seconds.

As given in the input, the only bicycle has 5010050100 probability to be damaged. So the expectation time cost is 50100×700+(1−50100)×220=46050100×700+(1−50100)×220=460.

题目描述:

输入两个速度,一个是骑行速度,一个是走路速度,下面有n-1个双向边,下面有q个自行车点,每个自行车有它坏的概率p,现在要求从1到n,问期望时间。

问题解析:

可以设置多个起点的最短路,把每个自行车点当作起点,算它到n的期望概率,Time = p(dis/t) + (1-p)(dis/r)。也可以用dp来做,它也可以先去另外一个自行车点,二进制为1代表这个点去过了,否则就代表没去过,所以就可以用二进制来做。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define close ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
const int N = 1e5 + 10;
const int inf = 1e18;
vector<pair<int, int>> edg[N];
vector<vector<int>> dis(19, vector<int>(N, inf)); 
vector<int> vis(N);
int t, r, n, m, k;
vector<vector<double>> dp(19, vector<double>((1 << 18), -1));
vector<int> pos(19, 0);
vector<double> p(19, 0);

void dij(vector<int> &dist, int s) {
    dist[s] = 0;
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
    q.push({0, s});
    while (!q.empty()) {
        int dt = q.top().first, u = q.top().second;
        q.pop();
        if (vis[u])
            continue;
        vis[u] = 1;
        for (auto i : edg[u]) {
            int v = i.first, w = i.second;
            if (dist[v] > dt + w) {
                dist[v] = dt + w;
                q.push({dist[v], v});
            }
        }
    }
}

double dfs(int u, int s) {
    if (dp[u][s] != -1) {
        return dp[u][s];
    }
    double res = p[u] * dis[u][n] / t + (1 - p[u]) * dis[u][n] / r;
    for (int i = 0; i < k; i++) {
        if (!(s >> i & 1)) {
            res = min(res, p[u] * (dfs(i, s | (1 << i)) + 1.0 * dis[u][pos[i]] / t) + (1 - p[u]) * dis[u][n] / r);
        }
    }
    return dp[u][s] = res;
}

void solved() {
    cin >> t >> r >> n >> m;
    for (int i = 1; i <= m; i++) {
        int u, v, w;
        cin >> u >> v >> w;
        edg[u].push_back({v, w});
        edg[v].push_back({u, w});
    }
    cin >> k;
    for (int i = 0; i < k; i++) {
        cin >> pos[i] >> p[i];
        p[i] /= 100.0;
    }
    map<int, int> mp;
    for (int i = 0; i < k; i++) {
        fill(dis[i].begin(), dis[i].end(), inf); 
        dij(dis[i], pos[i]);
        mp[pos[i]] = 1;
        fill(vis.begin(), vis.end(), 0); 
    }

    fill(dis[k].begin(), dis[k].end(), inf); 
    dij(dis[k], 1);

    if (!mp.count(1)) {
        p[k] = 1;
    }

    if (dis[k][n] == inf) {
        cout << -1 << endl;
        return;
    } else {
        cout << fixed << setprecision(10) << dfs(k, 0) << endl;
    }
}

signed main() {
    close;
    solved();
    return 0;
}


I: Power and Zero

Given a sequence A1,A2,⋯,AnA1,A2,⋯,An whose elements are all positive integers. You should do some operations to make the sequence all zero. For each operation, you can appoint a sequence B1,B2,⋯,Bm(Bi∈{1,2,⋯,n})B1,B2,⋯,Bm(Bi∈{1,2,⋯,n}) of arbitrary length mm and reduce ABiABi by 2i−12i−1 respectively. Specially, one element in the given sequence can be reduced multiple times in one operation. Determine the minimum possible number of operations to make the given sequence all zero.

Input

The first line contains one integer T(1≤T≤1000)T(1≤T≤1000), denoting the number of test cases.

For each test case:

The first line contains one integer n(1≤n≤105)n(1≤n≤105), denoting the length of given sequence.

The second line contains nn integers A1,A2,⋯,An(1≤Ai≤109)A1,A2,⋯,An(1≤Ai≤109), denoting the given sequence.

It is guaranteed that ∑n≤105∑n≤105.

Output

For each test case:

Output one line containing one integer, denoting the answer.

Example

Input

Copy

3
5
1 2 3 4 5
2
1 4
1
7

Output

Copy

3
3
1

Note

For the first sample case, one possible scheme:

  1. Appoint B={1,3,5}B={1,3,5}, then AA will be {0,2,1,4,1}{0,2,1,4,1}.
  2. Appoint B={3,2,4}B={3,2,4}, then AA will be {0,0,0,0,1}{0,0,0,0,1}.
  3. Appoint B={5}B={5}, then AA will be {0,0,0,0,0}{0,0,0,0,0}.

For the second sample case, one possible scheme:

  1. Appoint B={1,2}B={1,2}, then AA will be {0,2}{0,2}.
  2. Appoint B={2}B={2}, then AA will be {0,1}{0,1}.
  3. Appoint B={2}B={2}, then AA will be {0,0}{0,0}.

For the third sample case, one possible scheme:

  1. Appoint B={1,1,1}B={1,1,1}, then AA will be {0}{0}.

题目描述:

有T组数据,每组数据有n个数,我们需要求把这n个数全部变成0的最少次数,每一次操作可以选一个长度为m的序列去对数进行操作,减去2的0次到2的m次,可以对同一个数进行减,也可以对多个数进行减法。

问题解析:

我们把它转换成二进制中各个数的个数,当然二进制中0位置的个数肯定是都要减的,然后我们考虑从前往后递推知道完全一样的时候,如果前一个二进制位数比后一个数多的话,可以看作后一个位置减去2才能相当于前一个位置,所以按照最贪心的看法,直接对第一个位置减去3次数,对后一个位置+2次数,如果不是3的倍数就特殊处理一下。

#include <bits/stdc++.h>
#define close ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define int long long
#define endl '\n'
using namespace std;
vector<int> v(65);
void clear()
{
    for (int i = 0; i <= 64; ++i)
    {
        v[i] = 0;
    }
}
void solved()
{
    int n;
    cin >> n;
    vector<int> input(n + 1, 0);
    for (int i = 1; i <= n; i++)
    {
        cin >> input[i];
        bitset<65> myBit(input[i]);
        for (int i = 0; i <= 64; i++)
        {
            if (myBit[i])
            {
                ++v[i];
            }
        }
    }
    while (true)
    {
        int flag = 0;
        for (int i = 64; i > 0; i--)
        {
            if (v[i] > v[i - 1])
            {
                int dis = v[i] - v[i - 1];
                if (dis % 3 == 0)
                {
                    v[i] -= dis / 3;
                    v[i - 1] += dis / 3 * 2;
                }
                else
                {
                    v[i] -= dis / 3 + 1;
                    v[i - 1] += (dis / 3 + 1) * 2;
                }
                flag = 1;
            }
        }
        if (!flag)
        {
            cout << v[0] << endl;
            return;
        }
    }
}
signed main()
{
    close;
    int T;
    cin >> T;
    while (T--)
    {
        clear();
        solved();
    }
    return 0;
}


J: Local Minimum

Given a matrix of size n×mn×m. Determine the number of entries who equals the minimum value among all other entries of the same row or column. Formally, determine the value of

∑i=1n∑j=1m[min{Mu,v|u=iorv=j}=Mi,j]∑i=1n∑j=1m[min{Mu,v|u=iorv=j}=Mi,j]

Note: [A]=1[A]=1 if statement AA is true, or [A]=0[A]=0.

Input

The first line contains two integers n,m(1≤n,m≤1000)n,m(1≤n,m≤1000), denoting the size of given matrix.

Following nn lines each contains mm integers Mi,j(1≤Mi,j≤106)Mi,j(1≤Mi,j≤106), denoting the given matrix.

Output

Output one line containing one integer, denoting the answer.

Example

Input

Copy

3 3
1 5 9
4 3 7
2 6 2

Output

Copy

3

Note

There are 3 entries M1,1=1,M2,2=3,M3,3=2M1,1=1,M2,2=3,M3,3=2 satisfying the constraint.

题目描述:

有一个n*m的矩阵,求这个矩阵中某个位置是行的最小数字且是列的最小数字的位置的个数

问题解析:

模拟题,直接模拟完就可以了。

#include <bits/stdc++.h>
using namespace std;
#define int long long int
#define close ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
void solved()
{
    int n, m;
    cin >> n >> m;
    vector<int> minH(n + 1, 1e18);
    vector<int> minL(m + 1, 1e18);
    vector<vector<int>> input(n + 1, vector<int>(m + 1, 0));
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            cin >> input[i][j];
            minH[i] = min(minH[i], input[i][j]);
            minL[j] = min(minL[j], input[i][j]);
        }
    }
    int result = 0;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            if (input[i][j] == minH[i] && input[i][j] == minL[j])
            {
                ++result;
            }
        }
    }
    cout << result << endl;
}
signed main()
{
    close;
    solved();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值