hihoCoder挑戰賽37(暫時只有A題)
目錄
題目1 : XOR
時間限制:10000ms
單點時限:1000ms
記憶體限制:512MB
描述
給定非負整數x, k。請計算有多少個非負整數y滿足y + (x xor y) = x + k。其中+表示普通的整數加法,xor表示按位異或。如果有無窮個這樣的y,則輸出-1。
輸入
輸入一行包含兩個整數x, k。 (0 ≤ x, k ≤ 109)
輸出
輸出一行答案。
樣例解釋
y = 12, 13, 14, 15
樣例輸入
3 24
樣例輸出
4
題意分析:
1.題是什麼?
給你x,k,問你滿足y + (x xor y) = x + k的y有多少個,其實不存在無窮多個的情況,可以推理得知.
2.思路
(1).官方思路
k是奇數則無解,如果(k/2)&x!=0也無解, 令popcount為x的二進位制中1的個數,即是答案......
(2).我的思路
從位上下手,x,k小於十億,分析算式得知y也必然小於二十億,故而其實就是要確定y這32個二進位制位每個二進位制位是0還是1,而且由於算式的特殊性,x,k必須要給的合理才會存在答案,一道奇怪的題.
記住式子是y + (x xor y) = x + k
我們從位開始判斷,4*2只有8種情況
1.假設x的
假如y的位為1,只看這一位,1+1異或1 結果為1,不滿足x+k的0,必然無解
假如y的位為0,只看這一位,0+1異或0 結果為1,不滿足x+k的0,必然無解
2.假設x的位為0,x+k的位為1,
假如y的位為1,只看這一位,1+0異或1 結果為0,不滿足x+k的1,必然無解
假如y的位為0,只看這一位,0+0異或0 結果為0,不滿足x+k的1,必然無解
3.假設x的位為1,x+k的位為1,
假如y的位為1,只看這一位,1+1異或1
假如y的位為0,只看這一位,0+0異或1 結果為1,滿足x+k的1,無進位
4.假設x的位為0,x+k的位為0,
假如y的位為1,只看這一位,1+0異或1 結果為0,滿足x+k的0,進位1,此時x+k自然該減去進上來的這部分再遞迴(非常重要)
假如y的位為0,只看這一位,0+0異或0 結果為0,滿足x+k的0,無進位
上面的肯定看了暈,不過跟著想一想所有情況,想想就懂了,dfs判斷完這32位就好,理論上疑似存在爆棧風險,不過實際程式碼ac了.
3.ac程式碼
(1).官方解法
#include <stdio.h>
void solve(){
int x,k;
scanf("%d%d",&x,&k);
if(k%2||((k/2)&x)) printf("0\n");
else{
int ans=1;
while(x){
if(x&1) ans<<=1;
x>>=1;
}
printf("%d\n",ans);
}
}
int main(){
solve();
return 0;
}
(2).我的解法
#include <stdio.h>
int ans=0;
void dfs(int x,int xk,int power){//x是此時的x,xk是此時的x+k,power是此時的倍數
if(!x&&!xk){ //當兩個都為0,就可以收尾此支線了,y剩下的二進位制必取0
ans+=power;
return;
}
if((x&1)==1&&(xk&1)==1){
dfs(x>>1,xk>>1,power<<1);
}
else if((x&1)==0&&(xk&1)==0){
dfs(x>>1,xk>>1,power);
xk-=2; //很重要,對第7種情況產生的進位影響的抵消.
dfs(x>>1,xk>>1,power);
}
}
void solve(){
int x,k;
scanf("%d%d",&x,&k);
dfs(x,x+k,1);
printf("%d\n",ans);
}
int main(){
solve();
return 0;
}
題目2 : GCD
時間限制:5000ms
單點時限:1000ms
記憶體限制:512MB
描述
給定一個{1, 2, ..., n}的排列a[1], a[2], ..., a[n]。請問有多少對整數(i, j)滿足1 ≤ i ≤ j ≤ n,且gcd(i, j) = gcd(a[i], a[j]) = 1。這裡gcd表示最大公約數。
輸入
第一行包含一個整數n。 (1 ≤ n ≤ 200000)
第二行包含空格隔開的n個整數a[1], a[2], ..., a[n],保證是一個排列。
輸出
輸出一行答案。
樣例輸入
6
1 6 2 5 3 4
樣例輸出
10
題意分析
1.題是什麼?
給你一個大小n的數字序列,由打亂的1到n構成,問你任取1 ≤ i ≤ j ≤ n,gcd(i, j) = gcd(a[i], a[j]) = 1的方案有多少種?
2.思路
一道數論的題,看到這題我就知道我栽了,也別ac程式碼了,我理解一下公式先