%%%两个没素质的和一个萌两小时AK

最近貌似总是可以比较快速的拿下T1,然后T2打到考试结束。。。

T1是套路题没什么好说的。

T2是一个比较蠢的博弈题,我花了很长时间干各种乱七八糟的事

什么打表啊压表啊找规律啊找必胜策略啊。。。

因为时间复杂度的计算错误导致我浪费了大量时间干没用的事

最后发现刷表复杂度优秀就A了

然后中途留了20分钟左右暴打T3,因为打成子序列了40->0

而且更可惜的是其实已经很贴近正解思路了,就是没好好想好好打

然后虽说最终名次看起来还不错,但是实际上和上面直接就是100分的断档。

我这辈子什么时候能AK一回啊。。。

及时而正确地计算复杂度,注意观察真正有用的状态数,实在不行跑一遍试试。

看题。不管时间有多少,都要好好看题。

T1:异或

位运算类的套路题。二进制基本每次都是按位讨论。

因为异或运算的特殊性,每一位之间的贡献互不影响。

而只有当一个数是0另一个数是1时才会有值。

这样问题就转化为了[L,R]内第k位上是1的有多少个。

类似数位dp,直接求不好弄,我们用[0,R]的减去[0,L-1]的就是答案。

从0开始的要好统计一些。

可以发现某一位在二进制下的规律是00001111000011110000111100...

第k位的循环节长度是1<<k+1,其中有1<<k位是1。然后剩余的部分就是不足1<<k+1位,

在剩下的这么多位里1的个数是max(0,w%(1<<k+1)-(1<<k)+1)

然后就没了。我不知道怎么数位dp做。

 #include<cstdio>
#define mod 1000000007
long long up(long long x){return x>?x:;}
int main(){
int t,l,r;long long ans=,x;
scanf("%d",&t);
while(t--){
scanf("%d%d",&l,&r);ans=;
for(int i=;i<;++i){
x=r/(<<i+)-(l-)/(<<i+)<<i;
x+=up(r%(<<i+)-(<<i)+);
x-=up((l-)%(<<i+)-(<<i)+);
(ans+=x*(r-l+-x)%mod*(<<i+))%=mod;
}
printf("%lld\n",ans);
}
}

T2:取石子

博弈论?

反正一个比较明显的结论就是

如果你可以走向你个对手必败的局面,你就必胜,否则你必败。

所以我们就用每一个必败状态去扩展,扩展得到所有的必胜状态。

因为这道题里必败状态很少(10900个),所以刷表效率很高。

 #include<cstdio>
bool x[][][];
int main(){
for(int i=;i<=;++i)for(int j=i;j<=;++j)for(int k=j;k<=;++k)if(!x[i][j][k]){
for(int s=;s<=;++s)for(int a=;a<=;++a){
int I=i+(s&?a:),J=j+(s&?a:),K=k+(s&?a:);
if(I>||J>||K>)break;
if(I>J)I^=J^=I^=J;
if(I>K)I^=K^=I^=K;
if(J>K)J^=K^=J^=K;
x[I][J][K]=;
}
}
int t,a,b,c;scanf("%d",&t);
while(t--){
scanf("%d%d%d",&a,&b,&c);
if(a>b)a^=b^=a^=b;
if(a>c)a^=c^=a^=c;
if(b>c)b^=c^=b^=c;
puts(x[a][b][c]?"Yes":"No");
}
}

据说有人不知道什么叫刷表什么叫填表?

如果你外层枚举ijk,内层枚举xyz

刷表就是用dp[i][j][k]去更新dp[x][y][z]

填表就是用dp[x][y][z]去更新dp[i][j][k]

看似区别不大,但是在这道题里刷表是$O(10900M \times 7)$的,填表是$O(7 \times M^4)$的

因为刷表能利用必败状态少的这个性质(外层枚举必败状态)

而填表利用不了(外层什么都枚举,而内层去寻找必败状态)

T3:优化

一个常用的技巧就是遇到绝对值取最大值时,直接把绝对值去掉,正的负的都来一遍更新max,最后最优决策不会变差。

这样的话我们考虑如何dp。

相邻两段一定是一个加一个减。

那么相邻三段一共就有4种状态,中间那一段的贡献分别是+2,0,0,-2

然后用secret的思路设4种状态可做(听说还比较好做),而我写的是FACE的思路。

一个$O(n^2k)$的思路是设dp[i][j][0/1]表示到位置i恰好是某一个段结尾,已经用了j个段,上一段是减是加。

枚举ij,再枚举上一段的终点,找中间区间内最优的新区间起点。

加一些ST表来O(1)得到最优决策就好了,特殊处理最后一段就好了。

暴力就不细说了(稍懒,不然正解也写不完),直接给上代码吧。

 #include<cstdio>
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
int n,k,dp[][],dp2[][],x[],sum[];
int mn[][],mx[][],hi_bit[],ans;
int qmax(int l,int r){
int L=r-l+,B=hi_bit[L];
return max(mx[l][B],mx[r+-(<<B)][B]);
}
int qmin(int l,int r){
int L=r-l+,B=hi_bit[L];
return min(mn[l][B],mx[r+-(<<B)][B]);
}
int bg(int l,int r){
return sum[r]-qmin(l-,r-);
}
int sl(int l,int r){
return sum[r]-qmax(l-,r-);
}
int main(){
scanf("%d%d",&n,&k);
for(int i=;i<=n;++i)scanf("%d",&sum[i]),sum[i]+=sum[i-],mn[i][]=mx[i][]=sum[i];
for(int l=;l<;++l)for(int i=;i<=n+-(<<l);++i)
mn[i][l]=min(mn[i][l-],mn[i+(<<l-)][l-]),
mx[i][l]=max(mx[i][l-],mx[i+(<<l-)][l-]);
for(int l=;l<;++l)for(int j=<<l;j<<<l+;++j)hi_bit[j]=l;
for(int i=;i<=n;++i)for(int j=;j<=k;++j)dp[i][j]=dp2[i][j]=-;
dp[][]=dp2[][]=;
for(int i=;i<=n;++i)for(int j=;j<=k;++j)for(int f=;f<i;++f){
dp[i][j]=max(dp[i][j],dp[f][j-]+(f?:)*bg(f+,i)),
dp[i][j]=max(dp[i][j],dp2[f][j-]+(f?:)*bg(f+,i)),
dp2[i][j]=max(dp2[i][j],dp2[f][j-]-(f?:)*sl(f+,i)),
dp2[i][j]=max(dp2[i][j],dp[f][j-]-(f?:)*sl(f+,i));
}
for(int i=;i<=n;++i)for(int f=;f<i;++f)ans=max(ans,max(dp2[f][k-]+bg(f+,i),dp[f][k-]-sl(f+,i)));
printf("%d\n",ans);
}

T40

但是“恰好”这个限制条件是我们思维常见的一个误区,其实“恰好”并没有意义。

我们把它改成“至多/至少“的形式往往能让问题简单一些。

在这道题里,我们就可以转化为上一段区间的右端点在i左边(含),这样的话其实并不影响我们的决策。

有一个细节问题。就是最好在外层枚举k那一维(就叫它j了),不然会十分十分的麻烦。。。

首先我们需要特殊处理j=1的转移,其实它的含义就是 到i为止的 最大的子区间 的前缀最大值。

考虑具体做法,问题就是sum[i]-sum[p-1]。按照道理可能又需要枚举p了。

但其实开一个变量存下sum到i之前时的最小值。这样最大减最小就能得到最大的。

这样就可以得到dp[i][1][1]了,得到dp[i][1][0]其实是一样的就不细说了。

然后接下来的转移会麻烦一点,我们考虑从j=x到j=x+1的转移。

其中一个转移式子是这样的:

dp[i][j][1]=dp[f][j-1][0]+2*(sum[i]-sum[f])

这样的话怎么能不枚举f来弄?

其实就和上面j=1的情况一样了,可以发现dp[f][j-1][1]-2sum[f]与i毫无关联,依旧是开一个变量维护前缀最大值,不断更新就好。

其余的3个转移式子只需要分别维护一个变量就行了。大致同理。

j=k的那一步转移依旧需要特殊处理。

 #include<bits/stdc++.h>
using namespace std;
int n,k,dp[][][],s[],ans,_01,_00,_11,_10;//0- 1+
int main(){
scanf("%d%d",&n,&k);
for(int i=;i<=n;++i)scanf("%d",&s[i]),s[i]+=s[i-];
memset(dp,0xa0,sizeof dp);
for(int i=;i<=n;++i)
dp[][i][]=max(dp[][i-][],_01+s[i]),dp[][i][]=max(dp[][i-][],_10-s[i]),
_10=max(_10,+s[i]),_01=max(_01,-s[i]);
for(int j=;j<k;++j){
_01=_00=_11=_10=-1e9;
for(int i=;i<=n;++i)
dp[][i][j]=max(dp[][i-][j],max(_01+*s[i],_11)),
dp[][i][j]=max(dp[][i-][j],max(_10-*s[i],_00)),
_10=max(_10,dp[][i][j-]+*s[i]),_11=max(_11,dp[][i][j-]),
_01=max(_01,dp[][i][j-]-*s[i]),_00=max(_00,dp[][i][j-]);
}
_01=_00=_11=_10=-1e9;
for(int i=;i<=n;++i)
ans=max(ans,_01+s[i]),ans=max(ans,_10-s[i]),
_10=max(_10,dp[][i][k-]+s[i]),_01=max(_01,dp[][i][k-]-s[i]);
printf("%d\n",ans);
}

码倒不长。。

[考试反思]1024csp-s模拟测试86:消耗的更多相关文章

  1. [考试反思]0718 NOIP模拟测试5

    最后一个是我...rank#11 rank#1和rank#2被外校大佬包揽了. 啊...考的太烂说话底气不足... 我考场上在干些什么啊!!! 20分钟“切”掉T2,又27分钟“切”掉T1 切什么切, ...

  2. csp-s模拟测试86

    csp-s模拟测试86 分屋前的最后一次考试,我早就放弃了自己. 02:02:46 70 02:02:57 03:16:08 100 03:16:08 $T1$忘了按位计算,达哥按位计算的$T1$当时 ...

  3. 2019.10.25 csp-s模拟测试86 反思总结

    继续存档 早上来补了一下昨天的题,不过肯定这两天的没法完全补起来 T1: 经典思路:关于位运算的题讨论每一位的贡献 #include<iostream> #include<cstdi ...

  4. [CSP-S模拟测试86]题解

    好久没有写整套题的题解了呢……主要是这两天考试题愈发神仙 实在是超出了垃圾博主的能力范围啊QAQ A.异或 不难想到,如果我们得到了$[L,R]$中每一位上0和1的个数,那么答案即为$2 \times ...

  5. [考试反思]0814NOIP模拟测试21

    前两名是外校的240.220.kx和skyh拿到了190的[暴力打满]的好成绩. 我第5是170分,然而160分就是第19了. 在前一晚上刚刚爆炸完毕后,心态格外平稳. 想想前一天晚上的挣扎: 啊啊啊 ...

  6. [考试反思]1109csp-s模拟测试106:撞词

    (撞哈希了用了模拟测试28的词,所以这次就叫撞词吧) 蓝色的0... 蓝色的0... 都该联赛了还能CE呢... 考试结束前15分钟左右,期望得分300 然后对拍发现T2伪了写了一个能拿90分的垃圾随 ...

  7. [考试反思]0909csp-s模拟测试41:反典

    说在前面:我是反面典型!!!不要学我!!! 说在前面:向rank1某脸学习,不管是什么题都在考试反思后面稍微写一下题解. 这次是真的真的运气好... 这次知识点上还可以,但是答题策略出了问题... 幸 ...

  8. [考试反思]0729NOIP模拟测试10

    安度因:哇哦. 安度因:谢谢你. 第三个rank1不知为什么就来了.迷之二连?也不知道哪里来的rp 连续两次考试数学都占了比较大的比重,所以我非常幸运的得以发挥我的优势(也许是优势吧,反正数学里基本没 ...

  9. [考试反思]0714/0716,NOIP模拟测试3/4

    这几天时间比较紧啊(其实只是我效率有点低我在考虑要不要坐到后面去吹空调) 但是不管怎么说,考试反思还是要写的吧. 第三次考试反思没写总感觉缺了点什么,但是题都刷不完... 一进图论看他们刷题好快啊为什 ...

随机推荐

  1. 求n以内的质数(质数的定义:在大于1的自然数中,除了1和它本身意外,无法被其他自然数整除的数)

    思路: 1.(质数筛选定理)n不能够被不大于根号n的任何质数整除,则n是一个质数2.除了2的偶数都不是质数代码如下: /** * 求n内的质数 * @param int $n * @return ar ...

  2. Python调用 Openstack 主要服务(keystone,nova,glance,neutron,heat)

    由于Openstack更新很快,现在准备搭建基于Queen版本的Openstack,Queen版本要求keystone版本为V3,所以之前大多数接口都不能用了,百度了一下都没有比较新的实例,官方文档又 ...

  3. 报错fatal: refusing to merge unrelated histories

    提交到远程仓库的时候报错如下 是因为远程仓库有东西更新,但本地仓库没有更新造成提交失败 需要先把远程仓库给拉取下来,执行命令git pull origin master,又报错了如下 是因为两个仓库提 ...

  4. Lab_0操作系统实验准备(全)

    一.实验介绍 实验目的: 知识储备: 二.相关下载 1.下载镜像文件 这个镜像文件是vdi类型的,只能用visualbox下载 链接:https://pan.baidu.com/s/1L7WX6ju4 ...

  5. e课表项目第二次冲刺周期第七天

    昨天干了什么? 昨天我查找相关的资料实现对之前的信息连接数据库进行显示,完成修改的功能,并且返回到数据库当中.然后下午,我和我们小组的成员,讨论了第二个界面的具体功能和布局,我们一致同意,引用之前的第 ...

  6. sql数据文件导入数据库

    1.首先通过xshell连接数据库服务器,执行命令mysql -u root -p 命令,按照提示输入密码.连接上数据库. 2.在连接终端上执行命令create database JD_Model; ...

  7. 三种常见字符编码:ASCII、Unicode和UTF-8

    什么是字符编码? 计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255( ...

  8. [Noip1997] 棋盘问题(2)

    题目描述 在N×NN \times NN×N的棋盘上(1≤N≤10)(1≤N≤10)(1≤N≤10),填入1,2,…,N21,2,…,N^21,2,…,N2共N2N^2N2个数,使得任意两个相邻的数之 ...

  9. opencv::视频人脸检测

    视频流抓取人脸和眼睛 #include<opencv2/opencv.hpp> #include<iostream> using namespace cv; using nam ...

  10. Shiro 并发登录控制

    本文转载于:https://www.w3cschool.cn/shiro/epht1ifg.html