7.29题解

T1

不太难的一个真暴力,考试想的太复杂了,总觉得直接枚举块不现实,就进行了一大堆多余的处理,结果是三个半小时把自己搞到了崩溃,非常崩溃,结果自暴自弃了?打题的时候还好吧,一直在改,现在想想还不如重构,考后一个小时多一点就A掉了

就是个大暴力,分情况讨论,计算块与块之间的贡献就可以了,块内直接算没问题

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #define maxn 100100
 5 #define ll long long
 6 #define int long long
 7 using namespace std;
 8 struct tj{
 9     ll qx,qy,zx,zy;
10 }a[maxn];
11 int n;
12 ll ans;
13 bool cmp(const tj &a,const tj &b)
14 {
15     if(a.qx!=b.qx)  return a.qx<b.qx;
16     if(a.qy!=b.qy)  return a.qy<b.qy;
17     if(a.zx!=b.zx)  return a.zx<b.zx;
18     return a.zy<b.zy;  
19 }
20 signed main()
21 {
22     scanf("%lld",&n);
23     for(int i=1;i<=n;++i)
24     {
25         scanf("%lld%lld%lld%lld",&a[i].qx,&a[i].qy,&a[i].zx,&a[i].zy);
26         ans+=(a[i].zx-a[i].qx)*(a[i].zy-a[i].qy)*1ll*2;
27     }
28     sort(a+1,a+n+1,cmp);
29     for(int i=1;i<=n;++i)
30     {
31         for(int j=i+1;j<=n;++j)
32         {
33             if(a[j].qx>a[i].zx+1)  break;
34             if(a[j].qy>a[i].zy+1||a[j].zy+1<a[i].qy)  continue;
35             if(a[j].qy==a[i].zy+1)
36             {
37                 int ls1=min(a[i].zx,a[j].zx),ls2=max(a[i].qx,a[j].qx);
38                 ans+=(ls1-ls2)*2;
39                 if(a[i].qx!=a[j].qx)  ans++;
40                 if(a[i].zx!=a[j].zx)  ans++;
41                 if(ls2-ls1==1)  ans++;
42             }
43             else if(a[j].qx==a[i].zx+1)
44             {
45                 int ls1=min(a[i].zy,a[j].zy),ls2=max(a[i].qy,a[j].qy);
46                 ans+=(ls1-ls2)*2;
47                 if(a[i].qy!=a[j].qy)  ans++;
48                 if(a[i].zy!=a[j].zy)  ans++;
49                 if(ls2-ls1==1)  ans++;
50             }
51             else if(a[j].zx+1==a[i].qx)
52             {
53                 int ls1=min(a[i].zy,a[j].zy),ls2=max(a[i].qy,a[j].qy);
54                 ans+=(ls1-ls2)*2;
55                 if(a[i].qy!=a[j].qy)  ans++;
56                 if(a[i].zy!=a[j].zy)  ans++;
57                 if(ls2-ls1==1)  ans++;
58             }
59             else if(a[j].zy+1==a[i].qy)
60             {
61                 int ls1=min(a[i].zx,a[j].zx),ls2=max(a[i].qx,a[j].qx);
62                 ans+=(ls1-ls2)*2;
63                 if(a[i].qx!=a[j].qx)  ans++;
64                 if(a[i].zx!=a[j].zx)  ans++;
65                 if(ls2-ls1==1)  ans++;
66             }
67         }
68     }
69     printf("%lld\n",ans);
70     return 0;
71 }
暴力奇迹

 

T2

看见T2的时候其实就已经有点崩了,觉得它和之前的雨天的尾巴有点像,想往那个方向去,发现是个死胡同,怎么走都走不通,而且其实认定了自己线段树合并在考场上搞不出来,然后就弃掉了

刚才他们说这道题暴力+雨天的尾巴可以70分,我准备有时间搞一搞,正解估计又要留坑了

T3

这场考试最遗憾的一道题,最近看见概率与期望就想逃,需要重点练一练,这道其实不难,基本应该是可以想到,当然考场上我也不知道能不能,不过是个挺显然的转移方程

假设f[i][j]表示连续做了i道题,最大劳累值为j的方案数,是的,假期望,我们分两种情况,一个是最大值j是第i题贡献的,再一个就是最大值j是之前i-1道题中的某一道贡献的

所以,显然就是$f[i][j]=∑f[i-1][k]+f[i-1][j]*(j-1)$,如果是乘j-1前面k的范围就是$1<=k<=j$,如果乘j,前面k的范围就是$1<=k<=j-1$,就是保证那个选重复的情况不被包含两次且没人管就可以了,复杂度O(n3),鉴于n小,所以可做,如果n变大的话,可以选择用前缀和减少一维循环

 1 #include<iostream>
 2 #include<cstdio>
 3 #define maxn 510
 4 #define mod 1000000007
 5 #define ll long long
 6 using namespace std;
 7 int n,m,k;
 8 ll fz,fm,ans;
 9 ll w[maxn];
10 ll f[maxn][maxn];
11 ll ksm(ll a,ll b,ll c)
12 {
13     ll ans=1;  a=a%c;
14     while(b)
15     {
16         if(b&1)  ans=(ans*a)%c;
17         b=b>>1;  a=(a*a)%mod;
18     }
19     return ans;
20 }
21 int main()
22 {
23     scanf("%d%d%d",&n,&m,&k);
24     if(k>n)  {printf("0\n");  return 0;}
25     for(int i=1;i<=m;++i)  scanf("%lld",&w[i]);
26     for(int i=1;i<=m;++i)  f[1][i]=1ll*1;
27     for(int i=2;i<=k;++i)
28     {
29         for(int j=1;j<=m;++j)
30         {
31             f[i][j]=(f[i][j]+(f[i-1][j]*j)%mod)%mod;
32             for(int k=1;k<=j-1;++k)  f[i][j]=(f[i][j]+f[i-1][k])%mod;
33         }
34     }
35     fm=ksm(1ll*m,1ll*k,mod);
36     for(int i=1;i<=m;++i)  fz=(fz+(f[k][i]*w[i])%mod)%mod;
37     fm=ksm(fm,mod-2,mod);
38     ans=(((fz*fm)%mod)*1ll*(n-k+1))%mod;
39     printf("%lld\n",ans);
40     return 0;
41 }
最近最简单的概率期望

 

posted @ 2019-07-30 10:57  hzoi_X&R  阅读(147)  评论(0编辑  收藏  举报