UESTC 2018 Summer Training #2 Div.2 B、C、E、F、H、I

失恋了...所以昨晚一道题都没有补..

今天看到删好友他妈第一件事就是从ACM基地出来找地方哭。

不过还是自己的问题 很感谢有她的相遇。

刚才抓紧补了两题

B

Abood's birthday has come, and his n friends are aligned in a single line from 1 to n, waiting for their cookies, Abood has x cookies to give to his friends.

Here is an example to understand how Abood gives away the cookies. Suppose Abood has 4 friends and x cookies, then Abood will do the following:

  1. Give a cookie to the 1st friend.
  2. Give a cookie to the 2nd friend.
  3. Give a cookie to the 3rd friend.
  4. Give a cookie to the 4th friend.
  5. Give a cookie to the 3rd friend.
  6. Give a cookie to the 2nd friend.
  7. Give a cookie to the 1st friend.
  8. Give a cookie to the 2nd friend.
  9. And so on until all the x cookies are given away.

Your task is to find how many cookies each friend will get. Can you?

Input

The first line contains an integer T (1 ≤ T ≤ 100) specifying the number of test cases.

Each test case consists of a single line containing two integers x and n (1 ≤ x ≤ 1018, 1 ≤ n ≤ 1000), in which x is the number of cookies Abood has, and n is the number of his friends.

Output

For each test case, print a single line containing n space-separated integers a1, ..., an, in which ai represents how many cookies the ith friend got.

Example

Input

1
5 3

Output

2 2 1

总之昨天的集训给我的一种感觉就是你都会做,但是你就是处理不好那些小细节。

B题模拟一下就可以了。

1~n的情况,最后跑一遍肯定是:

—— —— —— —— ——

—— —— —— ——

        —— —— —— —— 

                —— ——

我们可以看到的是:第一行大家都有,然后开始的奇数个前N-1个有,偶数个后N-1有,最后一行再判断是第奇数个还是偶数个就可以得出结果。

注意的是:没跑完第一行的情况需要特判一下。

跑完第一行但是只有一个和两个的也需要特判一下。

#include<stdio.h>
long long A[105000];
int main()
{
	 int T;
	 scanf("%d",&T);
	 while(T--)
	 {
	 	long long x;
	 	long long n;
	 	scanf("%lld%lld",&x,&n);
			x-=n;
 		for(long long i=1;i<=n;i++)
 		{
		 	 A[i]=0;
		 }
 		if(n==1)
 		{
 			x++;
		    A[1]=x; 
			printf("%lld\n",A[1]);	
			continue;
	    }
	    if(n==2)
	    {
	    	x+=2;
    		A[1]=x/2;
    		A[2]=x/2;
    		if(x%2==1)
    		A[1]++;
    		printf("%lld %lld\n",A[1],A[2]);
    		continue;
    	}
 	if(x>0){long long  k=x/(n-1);
 		long long  d=x-(n-1)*(x/(n-1));	for(long long  i=1;i<=n;i++)
 		    A[i]=1;
 		for(long long i=2;i<=n-1;i++)
 		    A[i]+=k;
        if(d!=0)
        {
        	if(k-2*(k/2)==1)
           for(long long i=2;i<=d+1;i++)
              A[i]++;
           else
           {
           	  for(long long i=n-1;i>=n-d;i--)
           	  A[i]++;
           }
           
        }
        if(k==2*(k/2))
        {
        	A[1]+=k/2;
        	A[n]+=k/2;
        }
        else
        {
        	A[1]+=k/2+1;
        	A[n]+=k/2;
        }
	 }
     if(x<=0)
 	{
	 	
	 for(long long i=1;i<=x+n;i++)
		   A[i]++;
 	}
        for(long long i=1;i<=n;i++)
        printf("%lld ",A[i]);
        printf("\n");
        
 	 } }

 

C

You are given a positive integer n. Your task is to build a number m by flipping the minimum number of bits in the binary representation of n such that m is less than n (m < n) and it is as maximal as possible. Can you?

Input

The first line contains an integer T (1 ≤ T ≤ 105) specifying the number of test cases.

Each test case consists of a single line containing one integer n (1 ≤ n ≤ 109), as described in the statement above.

Output

For each test case, print a single line containing the minimum number of bits you need to flip in the binary representation of n to build the number m.

Example

Input

2
5
10

Output

1
2

C题是对2进制颠倒,需要保证反转的位数最小而且得到的数还尽可能的大,那我不可能从中间反转,中间反转之后一定会变小的

相对较多,我反转的时候需要从后面开始,遇到第一个1就反转,这样位数最少而且得到的数还尽可能大

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>

#define MOD 10000000
using namespace std; 
typedef long long LL;

long long quickpow(long long n, long long base) {
    long long res = 1;
    while(n) {
        if(n & 1) {
            res = res * base % MOD;
        }
        n >>= 1;
        base = base * base % MOD;
    }
    return res;
}//??? 

int A[10000];
int main()
{
   int T,n;
   cin>>T;
   while(T--)
   {
   	  cin>>n;
   	  int j=0;
      while(n)
   	  {
  	   	 A[++j]=n%2;
  	   	 n/=2;

      }
      int ans=0;
      for(int i=1;i<=j;i++)
      {
      	  if(A[i]==1)
      	  {ans++;break;}
      	  else ans++;
      }
      if(A[1]==1)ans=1;
      cout<<ans<<endl;
   }
}

E

E. N-Dimensional Grid

time limit per test

2.5 s

memory limit per test

256 MB

input

standard input

output

standard output

You are given an n-dimensional grid in which the dimensions of the grid are a1 × a2 × ... × an. Each cell in the grid is represented as an n-tuple (x1, x2, ..., xn) (1 ≤ xi ≤ ai).

Two cells are considered to be adjacent if the Manhattan Distance between them is equal to 1. The Manhattan Distance between two cells X(x1, x2, ..., xn) and Y(y1, y2, ..., yn) is equal to: |x1 - y1| + |x2 - y2| + ... + |xn - yn|.

Your task is to count how many pairs of cells are adjacents. Can you? Two pairs of cells are considered the same if they include the same cells, i.e the pair (c1, c2) is the same as (c2, c1).

Input

The first line contains an integer T (1 ≤ T ≤ 100) specifying the number of test cases.

The first line of each test case contains an integer n (1 ≤ n ≤ 105), in which n is the number of dimensions of the grid. Then a line follows containing n integers a1, ..., an (1 ≤ ai ≤ 105), in which ai is the size of the ith dimension.

The sum of n overall test cases does not exceed 6 × 106.

Output

For each test case, print a single line containing the number of pairs of adjacent cells modulo 109 + 7.

Example

Input

Copy

1
3
1 2 3

Output

Copy

7

Note

The absolute value |x| of a real number x is the non-negative value of x without regard to its sign. Namely, |x| = x for a positive x, |x| =  - x for a negative x (in which case  - x is positive), and |0| = 0. For example, the absolute value of 3 is 3, and the absolute value of  - 3 is also 3. The absolute value of a number may be thought of as its distance from zero.

E题就是推公式...公式很好推!

(a-1)*b*c+a*(b-1)*c+a*b*(c-1)=3*a*b*c-a*b*c*(1/a+1/b+1/c)=》n*A[1]*.....*A[n]-A[1]*.....*A[n]*(1/A[1]+1/A[2]+....1/A[n])

看到难点没有!求逆元。数论的一道题。

这里牵扯到了逆元。逆元是数论中对倒数和模相关的一个概念。

这两天会对逆元的知识做个系统化的了解。

先暂且用一个该题适合的。扩展欧几里得和费马小定理还不知道是啥这两种方法单独提。

这里引用一下https://blog.csdn.net/stcyclone/article/details/52081822

在求i的逆元时
p%i+[p/i]*i=p
令a=p%i,b=[p/i],则有
a+b*i=p
a+b*i=0(mod p)
b*i=-a(mod p)
i^-1=-b/a
也就是说i的逆元为:-[p/i]*(p%i)^-1
而p%i<i,那么可以从2递推到n求逆元,在求i之前p%i一定已经求出
这样就可以O(n)求出所有逆元了
(初始化 1^(-1)=1)
代码如下:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>

#define MOD 1000000007
using namespace std; 
typedef long long LL;

long long quickpow(long long n, long long base) {
    long long res = 1;
    while(n) {
        if(n & 1) {
            res = res * base % MOD;
        }
        n >>= 1;
        base = base * base % MOD;
    }
    return res;
}//??? 
int A[100050];

int BinSearch(int n,int k)
     {
     	int low=1,high=n,mid;
     	while(low<=high)
     	{
	        mid=(low+high)/2;
			if(k==A[mid])return mid;
			else if(k<A[mid])high=mid-1;
			else low=mid+1; 	
        }
        return 0;
     }
map<int ,int >map1;
LL sum;LL ans;
LL sum2;
int a;int b;
const int maxn=1e5+100;
LL inv[maxn];
void Prepare_inv(int n,int M){
    inv[1]=1;
    for(int i=2;i<=n;i++){
        inv[i]=(long long)(M-M/i)*inv[M%i]%M;
    } 
} 
int main()
{
	 Prepare_inv(maxn,MOD);
	 int T;
	 scanf("%d",&T);
	 while(T--)
	 {
 	   sum2=0;
 	   sum=1;
       int n; 
       scanf("%d",&n);
       for(int i=1;i<=n;i++)
       {
      	    scanf("%d",&A[i]);
            sum*=A[i];
            sum2+=inv[A[i]];
            sum2%=MOD;
            sum %=MOD;
       }
       ans=((n*sum)%MOD-(sum2*sum)%MOD+MOD)%MOD;
       cout<<ans<<endl;
	 }
     
} 

F

You are given an array a consisting of n integers a1, ..., an. In one operation, you can choose 2 elements ai and aj in which ai is divisible by aj and transform ai to aj.

A number x is said to be divisible by a number y if x can be divided by y and the result is an exact whole number. For example, 15 is divisible by 3, because 15÷ 3 = 5 exactly, but 9 is not divisible by 2 because 9÷ 2 is 4 with 1 left over.

Your task is to find the minimum sum of the array a that can be obtained by making as many transform operations as you want. Can you?

Input

The first line contains an integer T (1 ≤ T ≤ 100) specifying the number of test cases.

The first line of each test case contains an integer n (1 ≤ n ≤ 105), in which n is the size of array a. Then a line follows containing n integers a1, ..., an (1 ≤ ai ≤ 106), giving array a.

The sum of n overall test cases does not exceed 3 × 106.

Output

For each test case, print a single line containing the minimum sum of the array a that can be obtained after making as many transform operations as you want.

Example

Input

1
5
2 2 3 6 6

Output

11

做法难度不高:就是有点卡时间。排序之后从大到小然后每个i再从1~根号n找是否是A【i】的因数,是的话再看这个因数在不在数组中,再看这个因数的另一个因数在不在数组中,在的话先存起来,如果是前面这种情况就直接退出循环,后面这种情况就得遍历到最后,因为1-根号n一旦遇到一定是最小的,但如果是对应的另一个因数,那么肯定是1~根号n越大,这个对应因数越小,所以得遍历完,然后看退出循环之后有没有找到因数,再看找到因数之后是不是在前1~n的,如果是不用管,如果不在其中,令其等于你存起来的那个数,如果没有找到因数也不用管。

这里找数组元素在不在用map即可。超快因为元素不超过10e6所以不用担心超过内存。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>

#define MOD 10000000
using namespace std; 
typedef long long LL;

long long quickpow(long long n, long long base) {
    long long res = 1;
    while(n) {
        if(n & 1) {
            res = res * base % MOD;
        }
        n >>= 1;
        base = base * base % MOD;
    }
    return res;
}//??? 
int A[100050];

int BinSearch(int n,int k)
     {
     	int low=1,high=n,mid;
     	while(low<=high)
     	{
	        mid=(low+high)/2;
			if(k==A[mid])return mid;
			else if(k<A[mid])high=mid-1;
			else low=mid+1; 	
        }
        return 0;
     }
map<int ,int >map1;
LL sum;
int a;int b;
int main()
{

	int T,flag;
	scanf("%d",&T);
	while(T--)
	{
		sum=0;
		int n;
		scanf("%d",&n);
	    for(int i=1;i<=n;i++)
 	    {
   	     	  scanf("%d",&A[i]);
				map1[A[i]]=1;
	    }
	    sort(A+1,A+1+n);
        for(int i=n;i>=1;i--)
        {
        	flag=0;
        	a=sqrt(A[i]);
        	map1[A[i]]=0;
        	for(int j=1;j<=a;j++)
        	{
        		    if(A[i]%j==0)
                    {
				       if(map1[j])
                       {
					     A[i]=j;flag=1;
						 break;
                       }
                       else if(map1[A[i]/j])
                       {
                    	     b=A[i]/j;flag=2;
                       }
                    
					}
	        }
	        if(flag==2)A[i]=b;
	        sum+=A[i]; 
        }
        
        printf("%I64d\n",sum);
       
	}
} 

H

Ali is trying to make his friends happier by matching them into pairs together. In the beginning, Ali has 2 × n friends standing in a row and numbered from 1 to 2 × n. Each friend i will be matched with the friend numbered (2 × n - i + 1).

Each friend i has a happiness level equal to hi. The happiness level of a matched pair of friends i and (2 × n - i + 1) is equal to hi + h2 × n - i + 1.

Your task is to find the maximum happiness level of a pair among all matched pairs. Can you?

Input

The first line contains an integer T (1 ≤ T ≤ 50) specifying the number of test cases.

The first line of each test case contains an integer n (1 ≤ n ≤ 1000), giving that Ali has 2 × n friends. Then a line follows containing 2 × n integers h1, ..., h2 × n (1 ≤ hi ≤ 1000), in which hi represents the happiness level of the ith friend.

Output

For each test case, print a single line containing the maximum happiness level of a pair among all matched pairs.

Example

Input

1
3
2 4 5 6 7 8

Output

11
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>

#define MOD 10000000
using namespace std; 
typedef long long LL;

long long quickpow(long long n, long long base) {
    long long res = 1;
    while(n) {
        if(n & 1) {
            res = res * base % MOD;
        }
        n >>= 1;
        base = base * base % MOD;
    }
    return res;
}//??? 

int A[10000];
int sum;
int ans=0;
int main()
{
    int T;
    cin>>T;
    int n;
	while(T--)
    {
    	ans=0;
    	cin>>n;
    	for(int i=1;i<=2*n;i++)
    	cin>>A[i];
    	for(int i=1;i<=n;i++)
    	{
	    	sum=A[i]+A[2*n-i+1];
	    	ans=max(ans,sum);
	    }
	    cout<<ans<<endl;
    }
}

对于这道题真的很简单啊。但是一开始赋值ans没有等于0....WA了一次。

I

You are given an integer x. Your task is to split the number x into exactly n strictly positive integers such that the difference between the largest and smallest integer among them is as minimal as possible. Can you?

Input

The first line contains an integer T (1 ≤ T ≤ 100) specifying the number of test cases.

Each test case consists of a single line containing two integers x and n (1 ≤ x ≤ 109, 1 ≤ n ≤ 1000), as described in the statement above.

Output

For each test case, print a single line containing n space-separated integers sorted in a non-decreasing order. If there is no answer, print  - 1.

Example

Input

1
5 3

Output

1 2 2

Note

The strictly positive integers are the set defined as: . That is, all the integers that are strictly greater than zero: .

这题也很简单 但是我没看到有些情况要输出-1.. WA了一次。

这题做法就是先加上K,循环加上1,这样保证差值最多1.

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>

#define MOD 10000000
using namespace std; 
typedef long long LL;

long long quickpow(long long n, long long base) {
    long long res = 1;
    while(n) {
        if(n & 1) {
            res = res * base % MOD;
        }
        n >>= 1;
        base = base * base % MOD;
    }
    return res;
}//??? 

int A[10000];
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
    	int n;int k;
    	cin>>n>>k;;
    	int x=n/k;
    	if(k>n)
    	{
	    	cout<<"-1"<<endl;
	    	continue;
	    }
    	if(n%k==0)
    	{
	    	for(int i=1;i<=k;i++)
	    	{
	    		cout<<x<<" ";
	    	}
	    	cout<<endl;
	    }
	    else
	    {
    		for(int i=1;i<=k;i++)
    		A[i]=x;
    		int sum=x*k;
    		int i=0;
			while(sum<n)
    		{
		    	A[++i]++;
		    	sum++;
		    }
		    for(int i=k;i>=1;i--)
		    {
    			cout<<A[i]<<" ";
    		}
    		cout<<endl;
    	}
    }
}

接下里还起码得补个M、D。M题大佬讲了题解什么公共祖先然后啥啥啥啥的疯了。(题解就讲一遍谁听得懂qwq)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值