暑假集训

1010 Hazard and The Triangle

I’m Eden Hazard,the so-called “superb passer”. In a match in the group stage,three players surrounding me tried to block my advance,which,of course,failed. However,at that moment,they formed a triangle,which reminds me of an interesting problem about Pascal’s triangle.

The first element and the last element of each row in a Pascal’s Triangle is 1, and the m-th element of the n-th row equals to the sum of the m-th and the (m-1)-th element of the (n-1)-th row.Here’s an example.
1
1 1
1 2 1
1 3 3 1
1 4 6 3 1

I wonder how many elements in the k-th row of a Pascal’s Triangle are odd numbers.

Input

There are several test cases (no more than 500).
There is an integer K(K<10^18) in each case.
Output

For each test case, output the number of odd numbers in the -th line.
Input

3
4
5

Output

2
4
2

Code:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
    ll k;
    while(~scanf("%lld",&k))
    {
        ll res=1;
        k--;
        while(k){
            if(k&1)
                res=res*2;
            k>>=1;
        }
        printf("%lld\n",res);
    }
    return 0;
}

HINT
题意求杨辉三角第n行奇数个数。
题解
在这里插入图片描述
1011 Ibrahimovic and the Angry Cashier
I’m Zlatan Ibrahimović,the best soccer player on Earth. World Cup seems to be boring without me. Anyway,to entertain myself,I plan a days holiday. I decided to spend dollars on the th day.

I have M coins of 1-dollar and infinite bills of 100-dollar at the beginning. The cashier will always ask me to pay change-free.However,that’s not always possible. If the cashier has to give change,he will be displeased.

I want to minimize the displeasure of the cashier.The displeasure for each of the days is determined by x*Wi, where x represents the change and Wi represents the displeasure coefficients of the cashier for each of the days.

The cashier always has enough bills and coins to give change,while I can use the bills and coins he received in change during any of the following days. I want to know the minimum total displeasure of the cashier for these N days.

Cashier always gives change using as little coins and notes as possible, he always has enough of them to be able to do this.

Input

The first line contains an integer T,indicating that there are T test cases(1<=T<=20) .For each case:
The first line of the input contains two integers .N,M(N<=10^5,
M<=10^9)
The second line contains N integers Ci(1<=Ci<=10^5) .
The third line contains N integers Wi(1<=Wi<=10^5).
Output

For each test case, output the minimum displeasure of the cashier in one line.

Input

4
5 42
117 71 150 243 200
1 1 1 1 1
3 0
100 50 50
1 3 2
5 42
117 71 150 243 200
5 4 3 2 1
5 32
83 13 61 34 31
7 5 6 8 8

Output

79
150
230
353

Hint

(x,y) represents paying x bills and y coins in one day.
For test case 1,one possible condition is:
(1,17)(1,0)(2,0)(2,43)(2,0)
For test case 2,one possible condition is:
(1,0)(1,0)(0,50)
For test case 3,one possible condition is:
(1,17)(1,0)(1,50)(3,0)(2,0)
用到了升序优先队列。
找钱和纸币没有关系,所以所有的ci都对100取模。
然后统计出老板找钱时的怨气最的那一天交换硬币即可100-ci。
Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
priority_queue<ll, vector<ll>, greater<ll> > h;//升序优先队列
//priority_queue<int, vector<int>, less<int> > h; 降序优先队列
int main()
{
    int T;
    ll c[100005],w[100005];
    scanf("%d",&T);
    while(T--)
    {
        int n,m;
        scanf("%d %d",&n,&m);
        while (!h.empty()) h.pop();
        for(int i=0; i<n; i++)
        {
            scanf("%lld",&c[i]);
            c[i]%=100;
        }
        for(int i=0; i<n; i++)
        {
            scanf("%lld",&w[i]);
            w[i] *= 100 - c[i];
            //printf("%d ",w[i]);
        }
        ll mi=0,ans=0;
        for(int i=0; i<n; i++)
        {
            if (c[i] == 0)
            {
                continue;
            }
            mi+=c[i];
            h.push(w[i]);
            if(m<mi)
            {
                ans+=h.top();
                //printf("%d\n",h.top());
                h.pop();
                m+=100;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

1020 #include <deque>
Time Limit: 2 Seconds Memory Limit: 65536 KB
There is a deque of size n and you want to use it now, but unfortunately it’s not empty yet. So, before using it, you’re forced to do this boring work: clear it.

Each time you pop the i th number from the left side, you’ll get L * wi unhappiness points. Similarly, you’ll get R * wi unhappiness points if you take the i th number from the right side.

However, keep taking numbers from one side will make the work more boring. So if the previous operation is the same, you’ll get qL or qR extra unhappiness points, depending on the side you take numbers from. L , R , qL and qR are all constant. Now given L , R , qL , qR and the deque, you want to know the minimum unhappiness you can get.

Input

There are multiple test cases. For each test case: the first line contains 5 integers, n , L , R , qL and qR , seperated by a single space. the second line contains n integers, the i th integer is wi (1 ≤ n ≤ 100000, 1 ≤ n , L , R , qL , qR, wi ≤ 100)

Output

For each test case, output an integer in a line, indicating your answer.

Sample Input

2 3 4 5 6
1 2
5 1 10 1 100
1 2 3 4 5

Sample Output

11
19

Code:

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
int a[100005];
int dp[100005];
int main()
{
	int n,l,r,ql,qr;
	while(~scanf("%d%d%d%d%d",&n,&l,&r,&ql,&qr))
	{

		for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            dp[i]=dp[i-1]+a[i];
            //printf("%d ",dp[i]);
        }
		long long minn=INF;
		for(int i=0;i<=n;i++)
		{
			long long x=(dp[n]-dp[i])*r+dp[i]*l;//RlRl
			if(n-i>i+1)
			{
				x+=(n-i-i-1)*qr;//RRR
			}
			else if(i>n-i+1)
			{
				x+=(i+i-1-n)*ql;//LLL
			}
			minn=min(x,minn);
		}
		cout<<minn<<endl;
	}
	return 0;
}

HINT
在这里插入图片描述
1021 #include <list>
Time Limit: 2 Seconds Memory Limit: 65536 KB
For a sequence X. Xn+1 = ( a * Xn + c ) % p. Now given a, c, X0, n, p, you need to calculate Xn.

Input

The first line contains an integer T, indicating that there are T test cases (T <= 20);
For each case:
The only line of the input contains five integers a , c , X0 , n , p. ( a,c,p <= 1e9 , X0,n <= 1e18 )

Output

For each test case, output the integer Xn.

Sample Input

4
4 3 1 1 7
4 3 7 0 3
4 3 7 1 3
2018 7 15 8 31

Sample Output

0
7
1
10

HINT
线性递推 求Xn=(aXn-1+c)%p;
【Xn+1,1】=【Xn,1】*A
进行矩阵快速幂就可以了
Code:

#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int maxn=1e5+7;
const int INF= 1e9+7;
const int MOD=1e9+7;

LL p,a,c,x,n;
struct mat
{
    LL a[2][2];
};
mat mul(mat x,mat y)
{
    int i,j;
    mat ans;
    for(i=0; i<2; i++)
    {
        for(j=0; j<2; j++)
        {
            ans.a[i][j]=0;
            for(int k=0; k<2; k++)
            {
                ans.a[i][j]=(ans.a[i][j]+x.a[i][k]*y.a[k][j]%p)%p;
            }
        }
    }
    return ans;
}
mat mypow(mat tem,LL x)
{
    int i,j;
    mat ans;
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
        {
            if(i==j)ans.a[i][j]=1;
            else ans.a[i][j]=0;
        }

    int cnt=0;
    while(x)
    {
        //	printf("%d %lld\n",cnt++,x);
        if(x&1)
        {
            ans=mul(ans,tem);
        }
        tem=mul(tem,tem);
        x=x>>1;
    }
    return ans;
}
int main()
{
    int i,j,m,t,z;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld%lld%lld%lld%lld",&a,&c,&x,&n,&p);
        if(n==0)
        {
            printf("%lld\n",x);
            continue;
        }
        mat ans,tem;
        ans.a[0][0]=x;
        ans.a[1][0]=1;
        ans.a[0][1]=0;
        ans.a[1][1]=0;
        tem.a[0][0]=a;
        tem.a[1][0]=0;
        tem.a[0][1]=c;
        tem.a[1][1]=1;
        tem=mypow(tem,n);
        ans=mul(tem,ans);
        printf("%lld\n",ans.a[0][0]%p);
    }
    return 0;
}

1022 #include <bits/stdc++.h>
Time Limit: 2 Seconds Memory Limit: 65536 KB
C++ has many headers, but ZYH does not know about bits/std++.h and cannot memorize all the head documents. One day, he is inspired by the fact and decides to make his own bits/stdc++.h. Now there is a row of headers, a1,a2,…,an.

According to the rule, there are q (q ≤ 100000) operations. There are 4 types of operations. The first one is to combine ax and ay (i.e. combine the xth header and yth header in a same file. If they are in the same file now, ignore this operation). The second is to combine ax, ax+1, ax+2,…,ay together. The third one is to ask whether ax and ay have been combined into the same file, and the forth one is to ask the number of headers that the file containing ax have.

Note that x can be larger than y in case 2. If x > y, you need to combine ay, ay + 1 ,…,ax

Input

There are multiple test cases. The first line contains one integer T(1 ≤ T ≤ 5). For each test case, the first line contains two integers n, q (0 ≤ n ≤ 100000, 1 ≤ q ≤ 100000). Then the next q lines of each case contains two or three integer: t, x, y for type t = 1, 2, 3. or t, x for t = 4.

Output

For each t = 3, output “YES” or “NO” in one line as your answer. For each t = 4, output an integer in one line as your answer.
Sample Input

1
5 10
2 5 1
2 5 3
2 5 3
1 4 2
2 3 1
3 4 3
2 2 1
2 4 3
4 2
3 5 2

Sample Output

YES
5
YES

给定一个序列,进行任意2点合并,区间合并,询问size和2个点是否已被合并到一起。
查并集
Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int F[100005],sum[100005],next[100005];
int Find(int x)
{
    if(F[x]!=x)
        F[x]=Find(F[x]);
    return F[x];
}
void merge(int a,int b)
{
    int fx=Find(a);
    int fy=Find(b);
    if(fx!=fy)
    {
        F[fy]=fx;
        sum[fx]+=sum[fy];
    }
}
int main()
{
    int T;
    while(~scanf("%d",&T))
    {
        while(T--)
        {
            int n,q;
            scanf("%d %d",&n,&q);
            for ( int i=1 ; i<=n ; i++ )
            {
                F[i] = i;
                next[i] = i+1;
                sum[i] = 1;
            }
            for(int i =0; i<q; i++)
            {
                int t,x,y;
                scanf("%d",&t);
                if(t==1)
                {
                    scanf("%d %d",&x,&y);
                    merge(x,y);
                }
                else if(t==2)
                {
                    scanf("%d %d",&x,&y);
                    if(x>y)
                        swap(x,y);
                    while(next[x]<=y)
                    {
                        merge(x,next[x]);
                        int t=next[x];
                        next[x]=next[y];
                        x=t;
                    }
                }
                else if(t==3)
                {
                    scanf("%d %d",&x,&y);
                    if(Find(x)==Find(y))
                        printf("YES\n");
                    else
                        printf("NO\n");
                }
                else
                {
                    scanf("%d",&x);
                    printf("%d\n",sum[Find(x)]);
                }

            }
        }
    }


    return 0;
}

1037 Simple Counting
Time Limit: 2 Seconds Memory Limit: 65536 KB
To gain the Da♂rk power, you need to solve a math problem.
You are given two number N and K, and your task is to count how many X∈【1,N】 satisfies 【x的根号k次|x】.
Go and take the Da♂rk power!
Input

The input contains test cases.
For each case, there are two integers and .

Output

For each test case, output an integer which is the answer.(the key to the deep dark)

Sample Input

6 2
20 3
256 4

Sample Output

5
14
108

Hint

a|b means that b can be divided by a.
Code1打表,然后算当前这个区域的能被整除的数(n-c+s)/s,相加得出答案。
Code1:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    long long i,j,t,k;
    long long n,ans,x,a[100010][5];
    a[1][2]=3;
    a[1][3]=7;
    a[1][4]=15;
    for(i=2;i*i<2157583647;i++)
    {
        long long c=(i+1)*(i+1)-i*i+i-1;
        a[i][2]=a[i-1][2]+c/i;
    }
    for(i=2;i*i*i<2157583647;i++)
    {
        long long c=(i+1)*(i+1)*(i+1)-i*i*i+i-1;
        a[i][3]=a[i-1][3]+c/i;
    }
    for(i=2;i*i*i*i<2157583647;i++)
    {
        long long c=(i+1)*(i+1)*(i+1)*(i+1)-i*i*i*i+i-1;
        a[i][4]=a[i-1][4]+c/i;
    }
    while(scanf("%lld%lld",&n,&k)!=EOF)
    {
        int s=pow(n+1,1.0/k);
        long long c=1;
        for(i=0;i<k;i++)c*=s;
        long long ans=a[s-1][k];
        ans+=(n-c+s)/s;
        printf("%lld\n",ans);
    }
    return 0;
}

Code2:

#include<stdio.h>
#include<math.h>
int main()
{
    long long n,i,j,k;
    while (scanf("%lld %lld",&n,&k)!=EOF)
    {
        double t,q;
        long long p;
        t=n;
        q=k;
        p=(long long) pow(t,1.0/q);
        if (k==2)
        {
            if ((p+1)*(p+1)<=n)
                ++p;
            printf("%lld\n",(n-p*p)/p+1+3*(p-1));
        }
        else if (k==3)
        {
            if ((p+1)*(p+1)*(p+1)<=n)
                ++p;
            printf("%lld\n",(n-p*p*p)/p+1+4*(p-1)+p*(p-1)/2*3);
        }
        else if (k==4)
        {
            if ((p+1)*(p+1)*(p+1)*(p+1)<=n)
                ++p;
            printf("%lld\n",(n-p*p*p*p)/p+1+5*(p-1)+p*(p-1)*3+p*(p-1)*(2*p-1)/3*2);
        }
    }
    return 0;
}

1054 Bulbasaur and Exciting Number
Time Limit: 1 Second Memory Limit: 65536 KB
Bulbasaur receives T intervals as his birthday gift. He is very happy!

He decides to count the “Exciting Number” in these intervals. Let s(x) denote the “digit sum” of . For example, s(1234)=1+2+3+4=10,s(2333)=2+3+3+3=11 . If the integer x satisfies the equation p*(s(x))^k+q(k, q and are given in the input), then x is an “Exciting Number”.

Please help Bulbasaur count the number of “Exciting Number” in the interval [L,R].

Input

There are multiple test cases. The first line of the input is an integer T (about 10^5) indicating the number of test cases. For each test case:

The first and only line contains five integers k,p q,L, and R (1<=k<=5,-10…4<=q ,p<=104 ,1<=L<=R<=109).

Output

For each test case output one line containing an integer, indicating the answer.

Sample Input

2
2 2 -1 1 999
1 6 5 41 65

Sample Output

4
1

Hint

There are 4 Exciting Numbers in the first test case. They are 1, 31, 337, 967.

The only Exciting Number in the second test case is 53.
想从x开始循环次数就太多了 所以换一个思路从s(x)开始枚举,
最大值999999999所以s(999999999)=72.
Code:

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;

int main(){
	int t;
	int k,p,q,l,r,count=0;
	scanf("%d",&t);
	while(t--){
		count=0;
		scanf("%d%d%d%d%d",&k,&p,&q,&l,&r);
		for(int a=1;a<=72;a++){
			int x=(p*pow(a,k)+q),f=x,ans=0;
			while(f>0){
				ans=ans+f%10;
				f=f/10;
			}
			if(ans==a){
				if(x<=r&&x>=l)count++;
			}
		}
		printf("%d\n",count);
	}
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值