暑期集训test4

来源:互联网 发布:居外网软件下载 编辑:程序博客网 时间:2024/06/05 13:23

天天考试之后好不容易有一天拿着题解打完了三道题。
嗯,谈成绩伤感情,只看最后有没有掌握好了。
我差不多是一条死鱼了。。。。。
上题。

1.Permut

题目描述

求由 1 到 n 一共 n 个数字组成的所有排列中,逆序对个数为 k 的有多少个。

输入格式

第一行为一个整数 T ,为数据组数。
以下 T 行,每行两个整数 n,k,意义如题目所述。

输出格式

对每组数据输出答案对 10000 取模后的结果。

样例数据

输入 
1
4 1
输出
3

备注

对于 30% 的数据,满足:n≤12;
对于所有数据,满足:n≤1000, k≤1000,T≤10。

就是求逆序对,加了DP的思想。
然而状态转移方程太虐,一点想错全盘皆输。
如下。

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#define mod 10000using namespace std;int t,n,k;int f[1008][1008];int main(){    cin>>t;    for(int s=1;s<=t;s++)    {        memset(f,0,sizeof(f));        cin>>n>>k;        for(int i=0;i<=n;++i)             f[i][0]=1;               //初始化        for(int j=1;j<=k;++j)             f[0][j]=1;        for(int i=1;i<=n;++i)            for(int j=1;j<=k;++j)                if(j<i)                     f[i][j]=(f[i][j-1]+f[i-1][j])%mod;                else                     f[i][j]=(f[i][j-1]+f[i-1][j]-f[i-1][j-i]+mod)%mod;//加mod再%mod,不造成影响,将答案转为正数         cout<<(f[n][k]-f[n][k-1]+mod)%mod<<endl;    }    return 0;}

对就是上面那个方程,分类讨论了的那个。

2.Beautiful

题目描述

一个长度为 n 的序列,对于每个位置 i 的数 ai 都有一个优美值,其定义是:找到序列中最长的一段 [l,r] ,满足 l≤i≤r,且 [l,r] 中位数为ai(我们比较序列中两个位置的数的大小时,以数值为第一关键字,下标为第二关键字比较。这样的话 [l,r] 的长度只有可能是奇数),r-l+1 就是 i 的优美值。
接下来有 Q 个询问,每个询问 [l,r] 表示查询区间 [l,r] 内优美值的最大值。

输入格式

第一行输入 n 。
接下来 n 个整数,代表 ai。
接下来 Q ,代表有 Q 个区间。
接下来 Q 行,每行两个整数 l,r (l≤r),表示区间的左右端点。

输出格式

对于每个区间的询问,输出答案。

样例数据

输入
8
16 19 7 8 9 11 20 16
8
3 8
1 4
2 3
1 1
5 5
1 2
2 8
7 8

输出
7
3
1
3
5
3
7
3

备注

【数据规模】
对于 30% 的数据,满足:n,Q≤50;
对于 70% 的数据,满足:n,Q≤2000;
对于所有数据,满足 n≤2000;Q≤100000;ai≤200 。

当时做题的时候,首先排序就忽略了第一第二关键字,一团糟。
对于题目信誓旦旦的说一定是奇数一脸懵,不知所云。
好不容易写出来却发现自定义函数。。。。。嗯咳
上代码。

#include<iostream>#include<cstdlib>#include<cstdio>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>using namespace std;int n,q;int a[2005],w[2005],ll[4010],rr[4010];inline void zql(){    for(int i=1;i<=n;i++)    {        memset(ll,-1,sizeof(ll));        memset(rr,-1,sizeof(rr));        ll[n]=0;rr[n]=0;        int cnt=0;        for(int j=i-1;j>=1;j--)        {            if(a[j]>a[i])                cnt++;            else                cnt--;       //将大于看成是++,小于看成是--。            ll[n+cnt]=i-j;        }        cnt=0;        for(int j=i+1;j<=n;j++)        {            if(a[j]>=a[i])                cnt++;            else                cnt--;            rr[n+cnt]=j-i;        }        for(int j=1-i;j<=i-1;j++)            if(ll[n+j]>=0&&rr[n-j]>=0)                w[i]=max(w[i],ll[n+j]+rr[n-j]+1);    }}int main(){    //freopen("beautiful.in","r",stdin);    //freopen("beautiful.out","w",stdout);    cin>>n;    for(int i=1;i<=n;i++)        cin>>a[i];    zql();       //求每个数的优美值。    cin>>q;    while(q--)    {        int l,r;        cin>>l>>r;        int ans=0;        for(int i=l;i<=r;i++)            ans=max(ans,w[i]);        cout<<ans<<endl;    }    return 0;}

所以记录两边数的大小可以用+1或是-1的方式。

3.Subset

题目描述

一开始你有一个空集,集合可以出现重复元素,然后有 Q 个操作:
1. add s
在集合中加入数字 s 。
2. del s
在集合中删除数字 s 。保证 s 存在。如果有多个 s,只删除一个即可。
3. cnt s
查询满足 a&s=a 条件的 a 的个数。

输入格式

第一行一个整数 Q 接下来 Q 行,每一行都是 3 个操作中的一个。

输出格式

对于每个 cnt 操作输出答案。

样例数据

输入
7
add 11
cnt 15
add 4
add 0
cnt 6
del 4
cnt 15

输出
1
2
2

备注

【数据规模】
对于 30% 的数据满足:1≤n≤1000;
对于 100% 的数据满足:1≤n≤200000;0<s<2^16 。

显然题目清楚地指明了方向,只需要打出三个操作。
然而加粗的哪句话,当时并没有出现。(这就不能怪我了(摊手))
还有那个 真·神神秘秘·不知道是什么·让人一脸懵·a.
手动微笑。

#include<iostream>#include<cstdlib>#include<cstdio>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#include<queue>using namespace std;int n,k,k1,k2;int a[260][260];long long ans=0; char s[10];int main(){    //freopen("subset.in","r",stdin);    //freopen("subset.out","w",stdout);    cin>>n;    for(int i=1;i<=n;i++)    {        cin>>s;        cin>>k;        if(s[0]=='a')        {            k1=k/256;            k+=256;            k2=k%256;            for(int j=0;j<=255;j++)                if((j&k1)==k1)                    a[j][k2]++;        }           else if(s[0]=='d')        {            k1=k/256;            k+=256;            k2=k%256;            for(int j=0;j<=255;j++)                if((j&k1)==k1)                    a[j][k2]--;        }        else        {            ans=0;            k1=k/256;            k+=256;            k2=k%256;            for(int j=0;j<=255;j++)                if((j&k2)==j)                    ans+=a[k1][j];            cout<<ans<<endl;                }    }       return 0;   }

首先看数据范围,我们可以将其分成√n个块,每一次加减操作在每一个块中同时进行,而查询只需要在特定的块里查询,依旧是√n的复杂度。
总复杂度O(√n*√n).
(256=2^8)

来自2017.7.11.的test4 >o<

——我认为return 0,是一个时代的终结。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 早上上班忘记穿内衣了怎么办 高中知识都忘了怎么办 留鼻涕跟水一样怎么办 鼻涕像水一样流怎么办 肩膀很疼怎么办睡不着觉 夏天穿内衣出汗后很臭怎么办 脸过敏后严重缺水怎么办 过敏后脸上反复出现湿疹怎么办 孕妇脸上长湿疹过敏红肿怎么办 一岁宝宝一直流鼻涕怎么办 三岁宝宝一直流鼻涕怎么办 3岁宝宝一直流鼻涕不好怎么办 7岁半边鼻子不通气怎么办 感冒流鼻涕鼻子不通气怎么办 鼻子不通气干的怎么办 7个月婴儿流鼻涕怎么办 鼻子火辣辣的光想流鼻涕怎么办? 三岁宝宝鼻塞流鼻涕怎么办 一岁宝宝感冒流鼻涕鼻塞怎么办 1岁宝宝鼻塞流鼻涕怎么办 一岁多宝宝感冒鼻塞流鼻涕怎么办 宝宝鼻塞流鼻涕怎么办速效办法 八个月宝宝感冒流鼻涕鼻塞怎么办 7岁儿童流清鼻涕怎么办 1岁的宝宝流鼻涕怎么办 3岁宝宝鼻塞严重怎么办 宝宝流鼻涕2个月怎么办 一个月宝宝流鼻子怎么办 六个月宝宝流清水鼻涕怎么办 婴儿流鼻涕怎么办最简单方法 婴儿咳嗽流鼻涕怎么办最简单方法 6个月小孩流鼻涕怎么办 宝宝风寒感冒咳嗽流鼻涕怎么办 三个月宝宝流清鼻涕怎么办 三个月宝宝留清鼻涕怎么办 三个月婴儿流清鼻涕怎么办 宝宝7个月流鼻涕怎么办 6个月孩子流鼻涕怎么办 十一个月孩子感冒流鼻涕怎么办 7个月孩子流鼻涕怎么办 18个月的宝宝流鼻涕怎么办