【寒假集訓系列2.13】
又要爆零了...
第一題數學題,第二題打了一個錯誤的表,找到了錯誤的規律(漏加1),第三題騙分(不過只有10分)
總分:100+0+10=110
誒怎麽又是110,怕是跟police過不去了...
T1集合對
題目描述:
定義集合xor操作: A xor B=A∪B-A∩B。
問有多少對(P,Q)滿足 P∈A ,Q∈B 使得 (P xor A)xor(Q xor B)=A xor B其中P ,Q都是集合。(答案對1e9+7取模。)
例如:A ={1} ,B={1,2},A xor B = {2},枚舉所有情況P,Q有2種。
輸入:
三個整數a,b,c。表示|A|,|B|,|A∩B|。
輸出:
滿足要求的集合對。(輸出答案對10^9+7取模)
樣例輸入:
1 2 1
樣例輸出:
2
數據規模:
50%:a,b,c<=10^6
100%: a,b,c<=10^18
思路:xor是異或的意思嘛...然後這裏稍微轉換一下就發現答案是:
C(N,1)+C(N,2)+C(N,3)+...+C(N,N) = 2^N (N=|A∩B|))
然後顯然要快速冪啊...打上就好了...(把int #define成 long long了)
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define int long long #define ll long long const int MOD=1e9+7; using namespace std; inline int read(){ int ans=0,f=1;char chr=getchar(); while(!isdigit(chr)){if(chr==‘-‘) f=-1;chr=getchar();} while(isdigit(chr)) {ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();} return ans*f; } inline void kai(){ freopen("set.in","r",stdin); freopen("set.out","w",stdout); }long long a,b,c; int ksm(int x,int m){ if(m==1) return x; if(m==0) return 1ll; int t=ksm(x,m>>1);t=t*t%MOD; if(m&1) return t*x%MOD; return t; } signed main(){ // kai(); a=read(),b=read(),c=read(); int ans=ksm(2,c); cout<<ans; return 0; }
T2克拉克與數字
題目描述:
克拉克是一名人格分裂患者.某一天克拉克變成了一名數論研究者,在研究數字。
他想到了一個題:給定非負整數 x和正整數 k(1≤k≤2),可以做若幹以下兩種操作之一:
1. x=x-k
2. x=floor(sqrt(x))^2
現在克拉克想知道,這個整數最少經過多少次操作可以變成 0。
輸入:
第一行是一個正整數T,表示數據組數。每組數據只有一行兩個整數x, k。
輸出:
每組數據輸出一行一個整數,表示最少的操作數。若不存在方案,輸出-1。
樣例輸入:
2
2 1
3 2
樣例輸出:
2
-1
數據規模:
30%:x≤100
50%:x≤2*10^9
100%: 1≤T≤100,0≤x≤10^18, 1≤k≤2
那個啥,精度誤差了解一下...
當場打了一個搜索,暴力找規律,然後還真的找到了...
然而,爆搜打錯了...每個都漏了1,然後輸出的答案也漏了1...
正確思路好像是DP出小的數字答案,大的數字顯然是要開方更劃算的
Tip:
·註意精度誤差,系統自帶的sqrt可能對較大的數有些誤差,所以要調整一下(或者手打二分也可以),反正我搞這個搞了好久...
·小的數(小於5)沒規律,要打表
代碼如下:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #define int long long 7 using namespace std; 8 inline int read(){ 9 int ans=0,f=1;char chr=getchar(); 10 while(!isdigit(chr)){if(chr==‘-‘) f=-1;chr=getchar();} 11 while(isdigit(chr)) {ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();} 12 return ans*f; 13 } 14 inline void kai(){ 15 freopen("clarke.in","r",stdin); 16 freopen("clarke.out","w",stdout); 17 } 18 int T,x,y,ans; 19 int dfs2(int x){ 20 if(x<0||x==1) return -1; 21 if(x==0) return 0; 22 if(x==2) return 1; 23 int p=floor(sqrt(x));p*=p; 24 if(p==x) return dfs2(x-2)+1; 25 int t1=dfs2(x-2),t2=dfs2(p); 26 if(t1==-1) return t2+1; 27 return min(t1,t2)+1; 28 } 29 inline int Sqrt(int n){ 30 int x=sqrt(n); 31 if (x*x==n)return x; 32 if (x*x>n){while(x*x>n)x--;return x;} 33 else{while((x+1)*(x+1)<n)x++;return x;} 34 } 35 signed main(){ 36 kai(); 37 T=read(); 38 while(T--){ 39 x=read(),y=read(); 40 if(y==1){ 41 if(x==0) {puts("0");continue;} 42 int k=Sqrt(x);k*=k; 43 if(k==x) 44 ans=2*Sqrt(x)-1; 45 else ans=2*Sqrt(x); 46 printf("%lld\n",ans); 47 }else{ 48 if(x==5) {puts("3");continue;} 49 if(x<5){ 50 if(x==1||x==3) {printf("-1\n");continue;} 51 printf("%lld\n",dfs2(x)); 52 } 53 else 54 { 55 int k=Sqrt(x);k*=k; 56 if(k==x||k+1==x){ 57 ans=2*Sqrt(x)-3; 58 }else{ 59 ans=2*Sqrt(x)-2; 60 } 61 printf("%lld\n",ans+1); 62 } 63 } 64 } 65 return 0; 66 }
T3電壓
題目描述:
老胡的某個機房中有著復雜的電路。電路由n個節點和m根細長的電阻組成,節點被標號為1~N。
每個節點有一個可設定的狀態【高電壓】或者【低電壓】。每個電阻連接兩個節點,只有一端是高電壓,另一端是低電壓的電阻才會有電流流過。兩端都是高電壓或者低電壓的電阻不會有電流流過。
某天,老胡為了維護電路,選擇了一根電阻,為了能讓【只有這根電阻上的電流停止流動,其他M-1根電阻中都有電流流過】,需要調節各節點的電壓。為了滿足這個條件,能選擇的電阻共有多少根?
現在給出電路的信息,請你輸出電路維護時可以選擇使其不流的電阻的個數。
輸入:
第一行兩個空格分隔的正整數N和M,表示電路中有N個節點和M根電阻。
接下來M行,第i行有兩個空格分隔的正整數Ai和Bi(1<=Ai<=N,1<=Bi<=N,Ai≠Bi),表示第i個電阻連接節點Ai和節點Bi。
輸出:
輸出一行一個整數,代表電路維護時可選擇的使其不流的電阻個數。
樣例輸入:
4 4
1 2
2 3
3 2
4 3
樣例輸出:
2
樣例解釋:
可以選擇第一根電阻或第四根電阻。
數據規模:
50%:N<=1000,M<=2000
100%: 2<=N<=10^5,1<=M<=2*10^5
待填...
【寒假集訓系列2.13】