23333再次水惨了。。(心酸啊)
A题呵呵呵呵呵
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 int main() 5 { 6 int ans=0; 7 int n; cin>>n; 8 for (int i=1; i<=n; i++) 9 { 10 string ch; cin>>ch; 11 if (ch[0]=='T') ans+=4; 12 if (ch[0]=='C') ans+=6; 13 if (ch[0]=='O') ans+=8; 14 if (ch[0]=='D') ans+=12; 15 if (ch[0]=='I') ans+=20; 16 } 17 cout<<ans; 18 return 0; 19 }
B题,,,最后是不对的。。。(被fst了?我也不知道叫什么)
2333就是因为初始化变量的时候吧0x7fffffff达成了0x7ffffff(没错,少了一个f,,导致这个数比1e9小,然后就完蛋了)
1 #include<iostream> 2 #include<bits/stdc++.h> 3 using namespace std; 4 int main() 5 { 6 int n; cin>>n; 7 int ansy1=0x7fffffff,ansx1=0; 8 for (int i=1; i<=n; i++) 9 { 10 int x,y; cin>>x>>y; 11 ansy1=min(y,ansy1); 12 ansx1=max(x,ansx1); 13 } 14 int ansx2=0,ansy2=0x7fffffff; int m; cin>>m; 15 for (int i=1; i<=m; i++) 16 { 17 int x,y; cin>>x>>y; 18 ansx2=max(x,ansx2); 19 ansy2=min(ansy2,y); 20 } 21 cout<<max(0,max(ansx2-ansy1,ansx1-ansy2)); 22 }
C题比赛的时候还被hack了2333,,又是因为一个sb问题,(二分的右边界开小了,1e9是不够的。。呵呵呵,真的是到了晚上IQ=-inf了)
C题做的时候水的也比较惨,感觉暴力不对,就开始写二分。
n<m:然后一开始的前m天肯定是(直到m+1天的没吃之前,都是n),ans一开始直接搞成m,那么后面就是考虑这一天能不能被吃完,吃完的情况就是n-(x-1)*x/2<m+x的(这里的x是出去前m天,然后从1开始的),这是可以二分的。所以就各种调。。调到1个多小时。
1 #include<bits/stdc++.h> 2 #define LL long long 3 using namespace std; 4 LL n,m; 5 LL find(LL x) 6 { 7 LL l=0,r=3e9; 8 while (l<r) 9 { 10 LL mid=l+r>>1; 11 if (n-(mid-1)*mid/2==m+mid) return mid; 12 else if (n-mid*(mid-1)/2<m+mid) r=mid-1; 13 else if (n-mid*(mid-1)/2>m+mid) l=mid+1; 14 } 15 if (n-l*(l-1)/2>m+l) l++; 16 return l; 17 } 18 int main() 19 { 20 cin>>n>>m; 21 if (m>=n) 22 { 23 cout<<n; 24 return 0; 25 } 26 LL tot=n; 27 int cnt=1; 28 /*for (;;) //暴力手动对拍2333 29 { 30 tot+=m; if (tot>n) tot=n; 31 tot-=cnt++; 32 if (tot<=0) 33 { 34 cout<<cnt-1<<" "; 35 break; 36 } 37 }*/ 38 LL ans=0; 39 LL x=find(n); 40 ans=m; 41 cout<<ans+x; 42 return 0; 43 }
D题还是比较神的。一开始,心里想,yao这不是(组合数学?!!),(一般就不会了)
然而再一看还是挺简单的。。只需要对一个位置 i 搞出前面有多少个"(" (n个) 和后面有多少个")" (m个) 就好了,枚举每一个 “(” 的位置,每个位置的贡献就是 sigma(C(n-1,i-1)*C(m,i))(i: 1->min(n,m))
(取C(n-1,i-1)的原因就是要保证这一个"("一定要取到)
然而看了一下范围瞬间就蛋疼了。。(抱着侥幸的心理,感觉CF的评测机飞快,一秒跑个10的十几次方没什么问题吧(大雾),就写了那个暴力交上了。。第6个点就T了)
扒题解:有个神奇的东西交范德蒙恒等式!!!%%% http://blog.csdn.net/acdreamers/article/details/31032763
现在的每个位置的贡献貌似不能直接用范德蒙的那个公式算,,变一下形,变成 sigma(C(n,i)*C(m,i))-sigma(C(n',i)*C(m,i)) (i:1->min(n,m) (min(n',m)))(n'为上一个"("位置,"("的数量)
这样就可以用sigma(C(n,i)*C(m,i))==C(n+m,min(n,m))了,然而这个公式是从0开始的然后我们用的时候要减1,然后后面也减1就抵消了,,23333
这下直接秒A
里面还有一个处理逆元,阶乘什么的鬼东西(反正都是原来从题解上扒下来的)
(吐槽,我感觉这个sb公式要是白天脑子清醒的话能自己手玩(推)出来吧。。。。)
1 #include<bits/stdc++.h> 2 #define N 200005<<1 3 #define M 200000<<1 4 #define LL long long 5 using namespace std; 6 const int mod=1e9+7; 7 char ch[N]; 8 LL ans,fac[N],inv[N]; 9 int n,sum1[N],sum2[N]; 10 LL ksm(LL x, int p) 11 { 12 LL sum=1; 13 for (;p;p>>=1,x=x*x%mod) 14 if (p&1) sum=sum*x%mod; 15 return sum%mod; 16 } 17 LL C(int n, int m) 18 { 19 return fac[n]*inv[m]%mod*inv[n-m]%mod; 20 } 21 int main() 22 { 23 scanf("%s",ch+1); 24 n=strlen(ch+1); 25 for (int i=1; i<=n; i++) 26 if (ch[i]=='(') sum1[i]=sum1[i-1]+1; else sum1[i]=sum1[i-1]; 27 for (int i=n; i>=1; i--) 28 if (ch[i]==')') sum2[i]=sum2[i+1]+1; else sum2[i]=sum2[i+1]; 29 inv[0]=fac[0]=1; 30 for (int i=1; i<=M; i++) fac[i]=fac[i-1]*i%mod; 31 inv[M]=ksm(fac[M],mod-2); 32 for (int i=M; i>=1; i--) inv[i-1]=inv[i]*i%mod; 33 int last=0; 34 for (int i=1; i<=n; i++) 35 if (ch[i]=='(') 36 { 37 // cout<<C(last+sum2[i],min(last,sum2[i])); 38 ans=((ans+C(sum1[i]+sum2[i],min(sum1[i],sum2[i]))-C(last+sum2[i],min(last,sum2[i]))+mod)%mod)%mod;//while (1); 39 last=sum1[i]; 40 } 41 cout<<ans%mod; 42 return 0; 43 }