zoukankan      html  css  js  c++  java
  • 2017 Multi-University Training Contest 2

    官方题解

    1001 Is Derek lying?

    找出上下界直接判断

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 char s1[100005];
     4 char s2[100005];
     5 int n,a,b,c,d;
     6 int main(){
     7     int t;
     8     scanf("%d",&t);
     9     while(t--){
    10         a=0;
    11         scanf("%d%d%d",&n,&c,&d);
    12         scanf("%s%s",s1,s2);
    13         for(int i=0;i<n;i++){
    14             if(s1[i]==s2[i]) a++;
    15         }
    16         b=n-a;
    17         int L=max(0,c-b),R=0;
    18         if(a>c) R=c+b;
    19         else R=n-(c-a);
    20         if(d>=L&&d<=R){
    21             printf("Not lying
    ");
    22         }
    23         else{
    24             printf("Lying
    ");
    25         }
    26     }
    27 
    28 
    29     return 0;
    30 }
    Psong

    1002 hash

    1003 Maximum Sequence

    记录一个后缀最大值,贪心使每一个数最大。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int mod=1e9+7;
     4 int n;
     5 int a[500005];
     6 int b[500005];
     7 int suf[500005];
     8 int main(){
     9     while(scanf("%d",&n)!=EOF){
    10         int ans=0;
    11         memset(suf,0,sizeof(suf));
    12         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    13         for(int i=1;i<=n;i++) scanf("%d",&b[i]);
    14         sort(b+1,b+1+n);
    15         for(int i=n;i>=1;i--) suf[i]=max(suf[i+1],a[i]-i);
    16         ans=a[n+1]=suf[b[1]];
    17         int now=a[n+1]-(n+1);
    18         for(int i=n+2;i<=n*2;i++){
    19             a[i]=max(suf[b[i-n]],now);
    20             ans+=a[i]; ans%=mod;
    21         }
    22         printf("%d
    ",ans);
    23     }
    24 
    25     return 0;
    26 }
    Psong

    1004 Puzzle

    性质一:数列交换相邻两个数,逆序对奇偶性改变。

    性质二:以从左到右从上到下为顺序看作一个数列,不论如何改变最终逆序对奇偶性不变,因为空格总还是需要回到空格处,所以操作是会相互抵消。

    性质三:最终一定可以得到除了右下角的2*2以外,全都满足位置要求。

    求逆序对,判断奇偶。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 LL n,m,p;
     5 int main(){
     6     LL t;
     7     scanf("%lld",&t);
     8     while(t--){
     9         scanf("%lld%lld%lld",&n,&m,&p);
    10         LL ans=0,tot=n*m-1;
    11         while(tot>p){
    12             LL tmp=(tot+p-1)/p;
    13             LL last=(tmp-1)*(p-1);
    14             ans+=last*tmp/2;
    15             tot-=tmp;
    16         }
    17         if(ans%2==0) printf("YES
    ");
    18         else printf("NO
    ");
    19     }
    20 
    21     return 0;
    22 }
    Psong

    1005 Sdjpx Is Happy

    1006 Funny Function

    f[1][n]的通项可以求出,再向后计算可得f[m][1]的公式。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const LL mod=1e9+7;
     5 LL pow_mod(LL a,LL n){
     6     LL res=1,t=a;
     7     while(n){
     8         if(n&1) res=(res*t)%mod;
     9         t=(t*t)%mod;
    10         n/=2;
    11     }
    12     return res;
    13 }
    14 LL inv(LL x){
    15     return pow_mod(x,mod-2);
    16 }
    17 LL n,m;
    18 int main(){
    19     LL t;
    20     cin>>t;
    21     while(t--){
    22         cin>>n>>m;
    23         LL ans1=pow_mod(2,m)*pow_mod( (pow_mod(2,n)-1+mod)%mod,m-1 )%mod;
    24         LL ans2=pow_mod(-1,m)*pow_mod( (pow_mod(-1,n)-1+mod)%mod,m-1 )%mod;
    25         LL ans=(ans1-ans2+mod)%mod;
    26         ans=ans*inv((3*pow_mod(2,m-1))%mod)%mod;
    27         cout<<ans<<endl;
    28     }
    29 
    30     return 0;
    31 }
    Psong

    1007 If the starlight never fade

    1.原根:假设一个数g是P的原根,那么g^i mod P的结果两两不同,且有 1<g<P, 0<i<P,归根到底就是g^(P-1) = 1 (mod P)当且仅当指数为P-1的时候成立.(这里P是素数)。

    2.所有的数在取模的情况下都可以由原根的幂次表示,当模为1时,幂次为 p-1。

    3.若 gcd(n,i)=1 则 gcd(n,n-i)=1。

    4.由3可推出:[1,n]中与n互质的数的和为 phi(n)*n/2。

    官方题解推导(对于每一个y,x的取值个数相同):

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const LL mod=1e9+7;
     5 LL euler(LL n){
     6     LL ans=n;
     7     for(LL i=2;i*i<=n;i++){
     8         if(n%i==0){
     9             ans-=ans/i;
    10             while(n%i==0) n/=i;
    11         }
    12     }
    13     if(n>1) ans-=ans/n;
    14     return ans;
    15 }
    16 LL m,p,tmp;
    17 void add(LL &x,LL y){
    18     x%=mod; y%=mod;
    19     x=(x+y)%mod;
    20     if(x<0) x+=mod;
    21 }
    22 LL fun(LL x){
    23     if(x==1) return 1;
    24     else return (x*euler(x)/2)%mod;
    25 }
    26 int main(){
    27     LL t;
    28     scanf("%lld",&t);
    29     LL T=t;
    30     while(t--){
    31         scanf("%lld%lld",&m,&p);
    32         LL ans=0;
    33         add(ans,-(p*(p-1)/2%mod));
    34         for(int i=1;i*i<=p-1;i++){
    35             if((p-1)%i==0){
    36                 tmp=i;
    37                 add(ans,(tmp*tmp%mod)*fun((p-1)/tmp));
    38                 if(i*i!=p-1){
    39                     tmp=(p-1)/i;
    40                     add(ans,(tmp*tmp%mod)*fun((p-1)/tmp));
    41                 }
    42             }
    43         }
    44         printf("Case #%lld: %lld
    ",T-t,ans*m%mod);
    45     }
    46 
    47     return 0;
    48 }
    Psong

    1008 To my boyfriend

    每个数分开计算期望再求和。

    总数小于13的容斥,大于13的枚举不存在的情况。

    (13=log1e4)使得时间复杂度最小。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 LL n,m;
     5 LL a[105][105];
     6 vector<LL> pp[10005][105];
     7 vector<LL> num;
     8 struct node{
     9     LL x,y;
    10 };
    11 vector<node> poLL[10005];
    12 LL solve(LL u){
    13     LL res=0;
    14     for(LL i=1;i<=n;i++)
    15     for(LL j=1;j<=m;j++){
    16         if(a[i][j]==u) continue;
    17         LL ry=m+1;
    18         for(int k=i;k<=n;k++){
    19             for(int q=0;q<pp[u][k].size();q++){
    20                 if(pp[u][k][q]>=j) {
    21                     ry=min(ry,pp[u][k][q]);
    22                     break;
    23                 }
    24             }
    25             res+=ry-j;
    26         }
    27     }
    28     return res;
    29 }
    30 LL vis[20];
    31 void dfs(LL deep,LL u,LL times,LL &res){
    32     if(deep>=poLL[u].size()){
    33         if(times==0) return;
    34         LL lx=105,ly=105,rx=0,ry=0;
    35         for(LL i=0;i<poLL[u].size();i++){
    36             if(vis[i]){
    37                 lx=min(lx,poLL[u][i].x);
    38                 ly=min(ly,poLL[u][i].y);
    39                 rx=max(rx,poLL[u][i].x);
    40                 ry=max(ry,poLL[u][i].y);
    41             }
    42         }
    43         if(times%2==1) res+=(n-rx+1)*lx*(m-ry+1)*ly;
    44         else res-=(n-rx+1)*lx*(m-ry+1)*ly;
    45     }
    46     else{
    47         vis[deep]=1;
    48         dfs(deep+1,u,times+1,res);
    49         vis[deep]=0;
    50         dfs(deep+1,u,times,res);
    51     }
    52 }
    53 int main(){
    54     LL t;
    55     scanf("%lld",&t);
    56     while(t--){
    57         num.clear();
    58         scanf("%lld%lld",&n,&m);
    59         for(LL i=0;i<=n*m;i++){
    60             poLL[i].clear();
    61             for(int j=1;j<=n;j++) pp[i][j].clear();
    62         }
    63         for(LL i=1;i<=n;i++)
    64         for(LL j=1;j<=m;j++){
    65             scanf("%lld",&a[i][j]);
    66             num.push_back(a[i][j]);
    67             poLL[a[i][j]].push_back((node){i,j});
    68             pp[a[i][j]][i].push_back(j);
    69         }
    70         sort(num.begin(),num.end());
    71         num.erase(unique(num.begin(),num.end()),num.end());
    72         LL ans=0;
    73         LL tot=(n*(n+1)/2)*(m*(m+1)/2);
    74         for(LL i=0;i<num.size();i++){
    75             LL v=num[i];
    76             if(poLL[v].size()<=13){
    77                 memset(vis,0,sizeof(vis));
    78                 LL tmp=0;
    79                 dfs(0,v,0,tmp);
    80                 ans+=tmp;
    81             }
    82             else ans+=tot-solve(v);
    83         }
    84         printf("%.9lf
    ",(double)ans/tot);
    85     }
    86     return 0;
    87 }
    Psong

    1009 TrickGCD

    每一个区间gcd不为1,只要[1,n]的gcd不为1就好。

    记录每一个数出现的次数维护前缀和,求出当gcd为每个数的倍数时的总数。

    最后需要去重。

    (题解给的是莫比乌斯变换)

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const LL mod=1e9+7;
     5 LL n;
     6 LL a[100005];
     7 LL x[100005];
     8 LL sum[100005];
     9 LL num[100005];
    10 LL pow_mod(LL a,LL n){
    11     LL res=1,t=a;
    12     while(n){
    13         if(n&1) res=(res*t)%mod;
    14         t=(t*t)%mod;
    15         n/=2;
    16     }
    17     return res;
    18 }
    19 LL solve(LL x,LL min_num){
    20     LL res=1;
    21     LL tmp=min_num/x;
    22     while(tmp--){
    23         LL num=sum[min(x*(tmp+2)-1,100001LL)]-sum[min(x*(tmp+1)-1,100000LL)];
    24         if(num==0) continue;
    25         res=(res*pow_mod(tmp+1,num))%mod;
    26     }
    27     return res;
    28 }
    29 int main(){
    30     LL t;
    31     scanf("%lld",&t);
    32     LL T=t;
    33     while(t--){
    34         memset(num,0,sizeof(num));
    35         memset(sum,0,sizeof(sum));
    36         memset(x,0,sizeof(x));
    37         scanf("%lld",&n);
    38         LL L=100005,R=0;
    39         for(LL i=1;i<=n;i++){
    40             scanf("%lld",&a[i]); num[a[i]]++;
    41             L=min(L,a[i]); R=max(R,a[i]);
    42         }
    43         for(LL i=1;i<=100003;i++) sum[i]=sum[i-1]+num[i];
    44         for(LL i=2;i<=L;i++) x[i]=solve(i,R);
    45         for(LL i=L;i>=2;i--){
    46             for(LL j=i+i;j<=L;j+=i){
    47                 x[i]=(x[i]-x[j]+mod)%mod;
    48             }
    49         }
    50         LL ans=0;
    51         for(int i=1;i<=L;i++) ans=(ans+x[i])%mod;
    52 
    53         printf("Case #%lld: %lld
    ",T-t,ans);
    54     }
    55 
    56     return 0;
    57 }
    Psong

    1010 String and String

    1011 Regular polygon

    整点中只存在正四边形。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int n;
     4 int x[2005],y[2005];
     5 int vis[2005][2005];
     6 int main(){
     7     while(~scanf("%d",&n)){
     8         memset(vis,0,sizeof(vis));
     9         for(int i=1;i<=n;i++){
    10             scanf("%d%d",&x[i],&y[i]);
    11             x[i]+=500; y[i]+=500;
    12             vis[x[i]][y[i]]=1;
    13         }
    14         int ans=0;
    15         for(int i=1;i<=n;i++){
    16             for(int j=i+1;j<=n;j++){
    17                 int dx=x[i]-x[j];
    18                 int dy=y[i]-y[j];
    19                 if(vis[x[i]+dy][y[i]-dx]&&vis[x[j]+dy][y[j]-dx]) ans++;
    20                 if(vis[x[i]-dy][y[i]+dx]&&vis[x[j]-dy][y[j]+dx]) ans++;
    21             }
    22         }
    23         printf("%d
    ",ans/4);
    24     }
    25 
    26     return 0;
    27 }
    Psong
  • 相关阅读:
    【博客申明】
    OAF客制化代码导出页面数据到Excel文件
    OAF调用JS代码
    Java冒泡排序
    Java二分查找代码
    Java 在某一个时间点定时执行任务(转载)
    Oracle 常用SQL
    Oracle数据字典
    spring3.0事务管理配置
    由override 和 overload 引发的学习感悟
  • 原文地址:https://www.cnblogs.com/N-Psong/p/7252046.html
Copyright © 2011-2022 走看看