EDU div2#80 真丶被教育场

许久没打cf果然会变的好捞

C. Two Arrays

题目链接:https://codeforces.com/contest/1288/problem/C

题目大意   有两个长度为m的数组 a,b,a 非降序,b非升序   bi>=ai      1<=ai,bi<=n

问满足条件的  a b数组有多少个

  

将B数组翻转一下     bm>=am

则原题变为长度为2m的非降序数组有多少个,这就是个十分煞笔的DP

#include
using namespace std;
typedef long long ll;
const int N=3e5+7;
const ll mod=1e9+7;
int dp[1007][22];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        dp[i][1]=1;
    for(int j=1;j<=n;j++)
    {
        for(int i=2;i<=m*2;i++)
        {
            dp[j][i]=(dp[j][i-1]+dp[j-1][i-1])%mod;
        }
    }
    ll sum=0;
    for(int i=1;i<=n;i++)
    {
       sum+=dp[i][m*2];
       sum%=mod;
    }
    cout<

当然也有其他的很多好的方法,比如

翻转+公式法   C(2m,2m+n-1);直接就是答案

 

比如,不翻转

用二维数组保存答案,二维差分维护   dp[i][j]   i表示第i位,j表示第i位放的值

则递推公式为 dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+1;

 

D. Minimax Problem

题目链接:https://codeforces.com/contest/1288/problem/D

题目大意:选两个数组   每个位上的数字取两个数组该位置较大值 得到新的数组B   要使B数组最小值最大   输出你要选择的两个数组

思路  二分枚举B数组的最小值   然后比较每个数组和mid   会得到100010 类似的字符串s  二进制值记为sss   然后我们想要这个字符串1出现位置的子集,枚举1-2^m   如果  i&sss==i 则说明i是sss的子集,怎么判断mid成立与否呢,那就是例如 101101,只要010010存在就可以了,前面的子集部分都用一个数组存放的话就可以了,然后保存最后一个成立的数组的下标,和B数组最小值,然后暴力找前面的另一个满足条件的数组就可以了

代码有些乱,懒得优化了

好吧!还是整理了下,毕竟懒得已经只会去找容易的事情做了

#include
using namespace std;
typedef long long ll;
const int N=3e5+7;
const ll mod=1e9+7;
int di[N][10];
int n,m,ma,ans,tt;
int solve(int x)
{

       int f=0;
        int mid=x;
        int pan[300]={0};
        pan[0]=1;
        for(int i=0;i=mid)
                {
                    sss+=(1<=l)
            {
                sss+=(1<

 

 

赛前报名一时爽,赛后补题火葬场

比赛我唯唯诺诺,赛后我重拳出击

 

 

E. Messenger Simulator

题目链接:http://codeforces.com/contest/1288/problem/E

题目大意:就是发消息,本来n个人是以1-n的顺序,谁发一个消息就瞬间到首位置,给你他们发消息的序列,求每个人出现的最大位置和最小位置

大体思路:比如i  出现了两次  分别在103 和255 处  (n=500的话)  那么i的最大位置,就是初始值,103-255中出现的数的种数  255-n中出现的数的种数。三者中的最大值,多次和一次类似,没有出现过,位置的最大值就是比他大的数出现的种数+i,

现在的问题是怎样维护该数据,用什么样的数据结构

 

ans1- 线段树  or  树状数组   维护区间和

(以线段树为例,树状数组和这差不多的)

开m*2的线段树,所有数先放在m+1-2m处,l变量维护左边界,每当有人发消息的话,原位置变0,l变1,原位置到l区间和就更新一次答案。特殊处理没出现过的数即可

 

ans2- 莫队

存放每个数值出现的位置,生成一堆属于各个数的线段,求的是这些线段中数的种类个数,满足莫队算法要求,离线  O1修改 

如果不会莫队就去学一下,不难的很快的,sort下就好

这个的时间复杂度是比ans1 高一些的,但是题目没卡这种算法

 

具体代码不放了,因为有了思路这题就不难了,有兴趣自己敲下吧!

你可能感兴趣的:(比赛)