链接:戳这里
C. Bear and Forgotten Tree 3 time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard output A tree is a connected undirected graph consisting of n vertices and n - 1 edges. Vertices are numbered 1 through n.
Limak is a little polar bear and Radewoosh is his evil enemy. Limak once had a tree but Radewoosh stolen it. Bear is very sad now because he doesn't remember much about the tree — he can tell you only three values n, d and h:
The tree had exactly n vertices.
The tree had diameter d. In other words, d was the biggest distance between two vertices.
Limak also remembers that he once rooted the tree in vertex 1 and after that its height was h. In other words, h was the biggest distance between vertex 1 and some other vertex.
The distance between two vertices of the tree is the number of edges on the simple path between them.
Help Limak to restore his tree. Check whether there exists a tree satisfying the given conditions. Find any such tree and print its edges in any order. It's also possible that Limak made a mistake and there is no suitable tree – in this case print "-1".
Input
The first line contains three integers n, d and h (2 ≤ n ≤ 100 000, 1 ≤ h ≤ d ≤ n - 1) — the number of vertices, diameter, and height after rooting in vertex 1, respectively.
Output
If there is no tree matching what Limak remembers, print the only line with "-1" (without the quotes).
Otherwise, describe any tree matching Limak's description. Print n - 1 lines, each with two space-separated integers – indices of vertices connected by an edge. If there are many valid trees, print any of them. You can print edges in any order.
Examples
input
5 3 2
output
1 2
1 3
3 4
3 5
input
8 5 2
output
-1
input
8 4 2
output
4 8
5 7
2 3
8 1
2 1
5 6
1 5
Note
Below you can see trees printed to the output in the first sample and the third sample.
题意:给出一棵树,n个节点,直径为d,深度为h,要求画出满足条件的树即可,根节点必须为1
输出的话直接输出边就可以了
思路:首先如果树的深度*2都不能>=直径的话肯定是-1,还有就是n>=3的时候直径还小于2就构造不出来了,直径至少是2吧 所以这也是-1的情况
然后,树的根节点必须是1,树的直径必须是d,通过深度可以先填好直径,然后所有剩下来的点肯定都连1啊
但是会有问题,那就是至少连根节点1的情况下直径又+1,这个时候需要判断的就是当前的直径是否为0了
还有一种做法就是把树的直径按深度填好,然后直接无脑在2上连没有连的节点
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<iomanip>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
using namespace std;
int n,d,h;
int main(){
scanf("%d%d%d",&n,&d,&h);
if(h*2<d || (n>2 && d<2) ){
cout<<-1<<endl;
return 0;
}
int t=h,i=2;
while(t--){
cout<<i-1<<" "<<i<<endl;
i++;
d--;
}
int j=1;
if(d==0){
while(i!=n+1) {
cout<<2<<" "<<i<<endl;
i++;
}
}else {
while(d--){
cout<<j<<" "<<i<<endl;
j=i;
i++;
}
while(i!=n+1) {
cout<<1<<" "<<i<<endl;
i++;
}
}
return 0;
}
D. Bear and Polynomials time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard output Limak is a little polar bear. He doesn't have many toys and thus he often plays with polynomials.
He considers a polynomial valid if its degree is n and its coefficients are integers not exceeding k by the absolute value. More formally:
Let a0, a1, ..., an denote the coefficients, so
. Then, a polynomial P(x) is valid if all the following conditions are satisfied:
1:ai is integer for every i;
2:|ai| ≤ k for every i;
3:an ≠ 0.
Limak has recently got a valid polynomial P with coefficients a0, a1, a2, ..., an. He noticed that P(2) ≠ 0 and he wants to change it. He is going to change one coefficient to get a valid polynomial Q of degree n that Q(2) = 0. Count the number of ways to do so. You should count two ways as a distinct if coefficients of target polynoms differ.
Input
The first line contains two integers n and k (1 ≤ n ≤ 200 000, 1 ≤ k ≤ 109) — the degree of the polynomial and the limit for absolute values of coefficients.
The second line contains n + 1 integers a0, a1, ..., an (|ai| ≤ k, an ≠ 0) — describing a valid polynomial
. It's guaranteed that P(2) ≠ 0.
Output
Print the number of ways to change one coefficient to get a valid polynomial Q that Q(2) = 0.
Examples
input
3 1000000000
10 -9 -3 5
output
3
input
3 12
10 -9 -3 5
output
2
input
2 20
14 -7 19
output
Note
In the first sample, we are given a polynomial P(x) = 10 - 9x - 3x2 + 5x3.
Limak can change one coefficient in three ways:
He can set a0 = - 10. Then he would get Q(x) = - 10 - 9x - 3x^2 + 5x^3 and indeed Q(2) = - 10 - 18 - 12 + 40 = 0.
Or he can set a2 = - 8. Then Q(x) = 10 - 9x - 8x^2 + 5x^3 and indeed Q(2) = 10 - 18 - 32 + 40 = 0.
Or he can set a1 = - 19. Then Q(x) = 10 - 19x - 3x^2 + 5x^3 and indeed Q(2) = 10 - 38 - 12 + 40 = 0.
In the second sample, we are given the same polynomial. This time though, k is equal to 12 instead of 109. Two first of ways listed above are still valid but in the third way we would get |a1| > k what is not allowed. Thus, the answer is 2 this time.
题意:给出一个多项式F(x)=a0*x^1+a1*x^2+...+an*x^n 当x==2时 F(2)!=0 需要改变当且仅当一个系数ai的值使得Q(2)=0。
并且这个更改后的系数的绝对值不能超过k 且an!=0
思路:首先我们把它换位思考一下,当x=10的时候,我来描述一组样例
n=3 k=1e9
10 -9 -3 5
F(10)=10-9*10^1-3*10^2+5*10^3
我们要改变一个系数的值使得整个Q(10)=0 ,分析一下,如果在个位上的值是3的话,那么不管我怎么去改十位百位千位的值都无法使Q(10)=0,因为十位百位千位都无法变成3,都至少是10的倍数,那么问题就出现了,这个情况下我们只能通过改个位上的值去满足十位百位千位使得Q(10)=0.
下面我们回到原题,当x=2的时候,我们想象成二进制的数
n=3 k=1e9
10 -9 -3 5
F(2)=10-9*2^1-3*2^2+5*2^3
参照x=10的情况,当低位上存在值得时候,是无法通过更改高位的值使得Q(2)=0的。
所以我们只能更改低位上的值且当前低位上的系数为0的时候,才能使Q(2)=0.
所以我们把系数ai也换成二进制,然后问题也就差不多可以解决了
还需要注意的地方就是要先找出第一个ai不为0的位置,所以当前位置之前的所有位置上的系数都是0,这些位置都可以更改系数值
还需要注意的就是更改的值得范围不能超出k,基本上这道题就过了
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<iomanip>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
using namespace std;
int n,k;
int a[1000100],b[1000100];
int main(){
scanf("%d%d",&n,&k);
for(int i=0;i<=n;i++) {
scanf("%d",&a[i]);
b[i]=a[i];
}
for(int i=0;i<n;i++){
a[i+1]+=a[i]/2;
a[i]%=2;
}
int t=0;
for(int i=0;i<=n;i++){
if(a[i]==0) continue;
t=i;
break;
}
ll ans=0;
int num=0;
for(int i=n;i>=0;i--){
ans=ans*2+(ll)a[i];
if(abs(ans)>=1LL*1e9*1e9) break;
if(i<=t){
if(abs(ans-(ll)b[i])>k) continue;
if(i==n && abs(ans-(ll)b[i])==0) continue;
num++;
}
}
cout<<num<<endl;
return 0;
}<strong>
</strong>