链接:戳这里
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; }
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
0
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>