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

codeforce Hello 2020 B、C

时间:2020-01-05 15:44:44      阅读:71      评论:0      收藏:0      [点我收藏+]

标签:closed   cin   href   eof   n+1   under   nbsp   codeforce   close   

签到5分钟,挂机2小时 然后掉分

想了两个小时B,想着用树状数组维护数量,但实际上他不动态的去更改的话,似乎用个数组,最多再统计一下前缀和,即可实现树状数组的功能,太假了。后来想的set,pair。

总而言之,没把问题想透。

 

B New Year and Ascent Sequence

其实对一个序列而言,如果他存在一个递增的子序列,那么所有别的序列+这个序列合成产生的答案都是满足的。所以这些序列对答案的贡献n都是满的。

我们只对另一些序列进行操作,对于那些不存在递增子序列的序列,我们给他标记,并且统计他们最大值出现的次数。(这里我自己写烦了,如官方题解所说,这样的序列最大值肯定是第一个元素,最小值肯定是最后一个元素)

考虑从n*n中减去不满足的答案。

对这些序列的最大值出现次数求一下前缀和

最后遍历对每个不存在递增子序列的序列,减去最大值比当前序列最小值还要<=  的个数,最后得出来的就是答案了。

还有对上述序列最大值 排完序用lowerbound的做法,思想也是一样的。

 

技术图片
 1 #include <bits/stdc++.h>
 2 #ifndef ONLINE_JUDGE
 3 #define debug(x) cout << #x << ": " << x << endl
 4 #else
 5 #define debug(x)
 6 #endif
 7 using namespace std;
 8 typedef long long ll;
 9 const int MAXN=1e5+7;
10 const int INF=0x3f3f3f3f;
11 const int MOD=1e9+7;
12 
13 int ma[MAXN],mi[MAXN];
14 
15 int n,m;
16 
17 int arr[MAXN];
18 
19 int cnt[1100000];
20 int flag[110000];
21 
22 int main()
23 {
24     ios::sync_with_stdio(false);
25     cin.tie(0);
26     cin>>n;
27     memset(mi,0x3f,sizeof(mi));
28     for(int i=0,l;i<n;++i)
29     {
30         cin>>l;
31         for(int j=0;j<l;++j)
32         {
33             cin>>arr[j];
34             if(arr[j]>mi[i]) flag[i]=1;
35             ma[i]=max(ma[i],arr[j]);
36             mi[i]=min(mi[i],arr[j]);
37         }
38         if(!flag[i])
39             cnt[ma[i]]++;
40     }
41     ll ans=1ll*n*n;
42     for(int i=1;i<=1000000;++i) cnt[i]+=cnt[i-1];
43     for(int i=0;i<n;++i)
44     {
45         if(!flag[i])
46         {
47             debug(cnt[mi[i]]);
48             ans-=cnt[mi[i]];
49         }
50     }
51     cout<<ans<<\n;
52     return 0;
53 }
View Code

 

C New Year and Permutation

有趣的计数题,感觉可以当结论记住。题意就是对n的全排列,统计所有的[l,r]使得区间内的max-min==r-l,统计这样的l,r数量。

显然对于阶乘次数的每个排列去找这样的l,r,不太现实。统计也很困难。

我们不固定fix这个排列,而是固定一个l,r,对于一个长度为len=r-l+1的区间,(选择的是数必然是一个a~a+len-1的一个排列),这区间内的数的排列顺序组合有len!个,将这个区间缩成为一个数,算上剩余的数,就是(n-len+1),也就有(n-len+1)!个。

然后从长度为n的区间中选这样连续长len区间,又有n-len+1个选法,比如说 n=3,选len=2的区间,有两种选法。

然后式子就推出来了,然后对每个len 1~n 统计答案即可。

这也tql8.

写题解希望记住!主要还是思维吧,不从排列突破,从l,r的选取突破。

技术图片
 1 #include <bits/stdc++.h>
 2 #ifndef ONLINE_JUDGE
 3 #define debug(x) cout << #x << ": " << x << endl
 4 #else
 5 #define debug(x)
 6 #endif
 7 using namespace std;
 8 typedef long long ll;
 9 const int MAXN=3e5+7;
10 const int INF=0x3f3f3f3f;
11 const int MOD=1e9+7;
12 
13 ll fac[MAXN];
14 ll n,m;
15 int main()
16 {
17     ios::sync_with_stdio(false);
18     cin.tie(0);
19     cin>>n>>m;
20     fac[0]=1;
21     for(int i=1;i<MAXN;++i) fac[i]=fac[i-1]*i%m;
22     ll ans=0;
23     for(ll i=1;i<=n;++i)
24     {
25         ans+=(n-i+1)*fac[i]%m*fac[n-i+1]%m;
26         ans%=m;
27     }
28     cout<<ans<<\n;
29     return 0;
30 }
View Code

codeforce Hello 2020 B、C

标签:closed   cin   href   eof   n+1   under   nbsp   codeforce   close   

原文地址:https://www.cnblogs.com/Zzqf/p/12152384.html

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