码迷,mamicode.com
首页 > 其他好文 > 详细

2018 Multi-University Training Contest 4

时间:2018-08-05 15:20:14      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:turn   数字   转移   block   导出   nod   mod   一个人   can   

累惹。

 

B. Harvest of Apples

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6333

题意:求∑(i=0,m) C(n,m)。

分析:定义S(n,m)=∑(i=0,m) C(n,m)。可以知道:

S(n,m)=S(n,m-1)+C(n,m),S(n-m)=S(n-1,m-1)+S(n-1,m)=2*S(n-1,m-1)+C(n-1,m)。

由此可以推导出,由S(n,m)到S(n-1,m),S(n+1,m),S(n,m-1),S(n,m+1)的式子为:

S(n-1,m)=(S(n,m)+C(n-1,m))/2

S(n+1,m)=2*S(n,m)-C(n,m)

S(n,m-1)=S(n,m)-C(n,m)

S(n,m+1)=S(n,m)+C(n,m+1)

得到了四个方向的状态转移式,因此,可以用莫队离线处理。

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+10;
 4 const int mod=1e9+7;
 5 typedef long long ll;
 6 struct point{
 7     int n,m,block,id;
 8 }q[maxn]; 
 9 ll fac[maxn],inv[maxn],ans[maxn];
10 int res,Block;
11 void init(){
12     inv[0]=inv[1]=1;
13     for (int i=2;i<maxn;i++)
14         inv[i]=(mod-mod/i)*inv[mod%i]%mod; 
15 }
16 int comp(point p,point q){
17     return p.block<q.block || p.block==q.block && p.m<q.m;
18 }
19 
20 int main(){
21     init();
22     int t;
23     cin >> t;
24     Block=(int)(sqrt(t));
25     for (int i=0;i<t;i++){
26         cin >> q[i].n >> q[i].m;
27         q[i].id=i;
28         q[i].block=q[i].n/Block;
29     }
30     sort(q,q+t,comp);
31     ll n=0,m=0,nc=1,res=1;
32     for (int i=0;i<t;i++){
33         int nn=q[i].n,nm=q[i].m;
34         while (nn<n){
35             nc=nc*(n-m)%mod*inv[n]%mod;
36             res=(res+nc)%mod*inv[2]%mod;
37             n--;
38         }
39         while (nn>n){
40             res=(res*2%mod-nc+mod)%mod;
41             nc=nc*(n+1)%mod*inv[n+1-m]%mod;
42             n++;
43         }
44         while (nm<m){
45             res=(res-nc+mod)%mod;
46             nc=nc*m%mod*inv[n-m+1]%mod;
47             m--; 
48              
49         }
50         while (nm>m){
51             nc=nc*(n-m)%mod*inv[m+1]%mod;
52             res=(res+nc)%mod;
53             m++;
54         }
55         ans[q[i].id]=res;
56     }
57     for (int i=0;i<t;i++) cout << ans[i] << endl;
58     return 0;
59 } 
hdoj6333

 

D. Nothing is Impossible

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6335

题意:有若干道题,每题有1个正确选项,b个错误选项,问一个最优决策使得winner得分最大。

分析:如果仅有 1 道题,至少有一个人做对这题需要有 错误答案个数 + 1 个人。那么容易发现在每道题正确答案只有一个的情况下,如果 nn 道题中存在 ss 道题,使得学生人数 mm 不少于每道题 错误答案个数 + 1 相乘的结果,那么一定有人能够得到 ss 分。故我们将题目按错误答案个数从小到大排序,找到最大的 pp 满足技术分享图片就是答案。

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=110;
 4 struct node{int a,b,num;}a[N];
 5 bool cmp(node a,node b){return a.num<b.num;}
 6 int main(){
 7     int t,n,m;scanf("%d",&t);
 8     while(t--){
 9         scanf("%d%d",&n,&m);
10         for(int i=1;i<=n;i++) scanf("%d%d",&a[i].a,&a[i].b),a[i].num=a[i].a+a[i].b;
11         sort(a+1,a+n+1,cmp);
12         int tmp=m;int cnt=-1;
13         for(int i=1;i<=n;i++){
14             int num=a[i].num;
15             int nn=tmp/num;
16             tmp=nn*a[i].a;
17             if(tmp<1) break;
18             cnt=i;
19         }
20         printf("%d\n",cnt);
21     }
22     return 0;
23 }
hdoj6335

 

E. Matrix from Arrays

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6336

题意:根据题意构造一个矩阵,求子矩阵和。

分析:打表发现矩阵有循环节。n为奇数时循环节为n*n,n为偶数时循环节为2*n*2*n。求出循环节二维前缀和,再扩展到普通矩阵求和即可。

技术分享图片
 1 #include<iostream>
 2 #include<cstring>
 3 #define maxn 500
 4 using namespace std;
 5 typedef long long ll;
 6 int mp[maxn][maxn],a[maxn];
 7 int L;
 8 void init(){
 9     int cursor = 0;
10     for (int i = 0;i<4*L; ++i) {
11         for (int j = 0; j <= i; ++j) { 
12             mp[j][i - j] = a[cursor];
13             cursor = (cursor + 1) % L;
14         }
15     }
16     L*=2;
17     for (int i=0;i<L;i++)
18         for (int j=0;j<L;j++){
19             if (i) mp[i][j]+=mp[i-1][j];
20             if (j) mp[i][j]+=mp[i][j-1];
21             if (i && j) mp[i][j]-=mp[i-1][j-1];
22          }
23 }
24 ll calc(int x,int y){
25     if (x<0 || y<0) return 0;
26     ll res=0;
27     res=1ll*mp[L-1][L-1]*(x/L)*(y/L)+1ll*mp[x%L][L-1]*(y/L)+1ll*mp[L-1][y%L]*(x/L)+1ll*mp[x%L][y%L];
28     return res;
29 }
30 ll slove(){
31     int l1,r1,l2,r2;
32     ll res=0;
33     cin >> l1 >> r1 >> l2 >> r2;
34     res=calc(l2,r2)-calc(l1-1,r2)-calc(l2,r1-1)+calc(l1-1,r1-1);
35     return res;
36 }
37 int main(){
38     ios::sync_with_stdio(false);
39     cin.tie(0);cout.tie(0);
40     int t,q;
41     cin >> t;
42     while (t--){
43         cin >> L;
44         for (int i=0;i<L;i++) cin >> a[i];
45         init();
46         cin >> q;
47         while (q--){
48             ll ans=slove();
49             cout << ans << endl;
50         }
51     }
52     return 0;
53 }
hdoj6336

 

K. Expression in Memories

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6342

题意:在?处填入数字0-9或+,*使得表达式合法。

分析:填入1或+即可。

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 bool is1(char c){
 4     return c==+||c==*;
 5 }
 6 int main(){
 7     std::ios::sync_with_stdio(false); 
 8     int t;string s;cin>>t;
 9     while(t--){
10         cin>>s;s=++s;int len=s.size();
11         for(int i=1;i<len;i++){
12             if(s[i]==?){
13                 if(s[i-1]==0&&(s[i-2]==+||s[i-2]==*)) s[i]=+;
14                 else s[i]=1;
15             }
16         }
17         int flag=1;
18         for(int i=1;i<len;i++){
19             if(is1(s[i])&&is1(s[i-1])) flag=0;
20             if(i==len-1) break; 
21             if(is1(s[i-1])&&s[i]==0&&!is1(s[i+1])) flag=0;
22         }
23         string ans="";
24         for(int i=1;i<len;i++) ans+=s[i];
25         if(is1(s[len-1])) flag=0;
26         if(flag) cout<<ans<<"\n";
27         else cout<<"IMPOSSIBLE"<<"\n";
28     }
29     return 0;
30 }
hdoj6342

 

L. Graph Theory Homework

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6343

题意:起点1,终点n,中间可经过任意点。求1-n的最小距离。

分析:容易证明:|sqrt(a)| + |sqrt(b)| > |sqrt(a+b)| ,边权满足三角不等式,故直接从1-n距离最小。

技术分享图片
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cmath>
 4 #define maxn 100005
 5 using namespace std;
 6 int a[maxn];
 7 int main(){
 8     ios::sync_with_stdio(false);
 9     cin.tie(0);cout.tie(0); 
10     int t,n;
11     cin >> t;
12     while (t--){
13         cin >> n;
14         for (int i=1;i<=n;i++) cin >> a[i];
15         int ans=(int)sqrt(abs(a[1]-a[n]));
16         cout << ans << endl;
17     }
18     return 0;
19 } 
hdoj6343

 

2018 Multi-University Training Contest 4

标签:turn   数字   转移   block   导出   nod   mod   一个人   can   

原文地址:https://www.cnblogs.com/changer-qyz/p/9425548.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!