题面:https://www.cnblogs.com/Juve/articles/11736440.html

异或:

考试时只想出了暴力

我们可以对于二进制下每一位w,求出[l,r]中有几个数在这一位是1,记为x,设y表示[l,r]中有几个数在w位不是一

这样就会有x×y对数在w位上产生贡献,每一对数会有2w的贡献,

主要就是实现一个calc函数,calc(x,i)表示从0到x有多少的数二进制下第i位是1,然后我们发现一个规律:

如果把0~9二进制打印出来:










发现每一位是循环的,第0位循环节是2。第1位是4,第2位是8,而且只有没一个循环节的后一半是1,所以根据这个我们实现了calc函数

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
#define re register
using namespace std;
const int mod=1e9+;
int t,l,r,ans;
inline int q_pow(re int a,re int b,re int p){
re int res=;
while(b){
if(b&) res=res*a%p;
a=a*a%p;
b>>=;
}
return res;
}
int qpow(int a,int b){
int res=;
while(b){
if(b&) res=res*a;
a=a*a;
b>>=;
}
return res;
}
int calc(int x,int pos){
++x;
int res=;
int tmp=qpow(,pos+);
int q=x/tmp;
res+=q*tmp/;
int p=x%tmp;
if(p>tmp/) res+=p-tmp/;
return res;
}
signed main(){
scanf("%lld",&t);
while(t--){
scanf("%lld%lld",&l,&r);
ans=;
for(int i=;i<=;++i){
ans=(ans+(r-l+-(calc(r,i)-calc(l-,i)))*(calc(r,i)-calc(l-,i))%mod*q_pow(,i,mod)%mod)%mod;
}
printf("%lld\n",*ans%mod);
}
return ;
}

取石子:

第一次做博弈论,然后我考试AC了。。。

其实不能算是裸的博弈,毕竟我认为是dp

一开始打搜索,发现不会打,打了2个多小时,然后突然发现可以dp筛出状态,然后打了正解,最后30分钟交上去AC了

设g[i][j][k]表示三堆石子数量为i,j,k时能否先手必胜

我们发现如果有x,y,z必输,那么x,y,z+k;

              x+k,y,z;

              x,y+k,z;

              x+k,y+k,z;

              x+k,y,z+k;

              x,y+k,z+k;

              x+k,y+k,z+k一定必胜

因为先手可以通过x+k,y+k,z+k都拿走k,变成x,y,z从而让对手必输

然后我们就可以转移了,从0,0,0开始,如果找到了一个必输的,那么用它更新后面必胜的,有些类似线性筛

虽然有4层循环,但是一般不会进第4个循环,就像线性筛一样,总的复杂度还是O(n3)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define re register
using namespace std;
int t,x,y,z;
bool g[305][305][305];
inline void pre(){
for(re int i=0;i<=300;++i){
for(re int j=0;j<=300;++j){
for(re int k=0;k<=300;++k){
if(g[i][j][k]) continue;
for(re int p=1;p<=300;++p){
re int a=min(301,i+p),b=min(301,j+p),c=min(301,k+p);
if(a+b+c>=903) break;
g[a][j][k]=g[i][b][k]=g[i][j][c]=1;
g[a][b][k]=g[a][j][c]=g[i][b][c]=1;
g[a][b][c]=1;
}
break;
}
}
}
}
signed main(){
pre();
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&x,&y,&z);
if(g[x][y][z]) puts("Yes");
else puts("No");
}
return 0;
}

优化:

看到绝对值要想着去绝对值

我们让每一个数都必选,那么每一个数a对整个答案的贡献可能是2a,-2a,a,-a,0

a和-a之存在与第一段和最后一段,系数是2就是a所在的区间比它左右区间的元素的和都大,具体来说就是:

2的情况:

$|s_{i-1}-s_i|+|s_i-s_{i+1}|=2*s_i-s_{i-1}-s_{i+1}$,

-2的情况和2的相反

0的情况:

$|s_{i-1}-s_i|+|s_i-s_{i+1}|=s_{i-1}-s_i+s_i-s_{i+1}$或$|s_{i-1}-s_i|+|s_i-s_{i+1}|=s_i-s_{i-1}-s_i+s_{i+1}$

然后就可以dp转移了,设f[i][j][4]表示前i个,划分了j个区间的最大值,

我们定义正为上升,负为下降,那么0表示上升,1表示下降,2表示从上升到下降,3表示从下降到上升

然后狗shi的转移:

 if(j==||j==k){
f[i][j][]=max(f[i-][j][],f[i-][j-][])+a[i];
f[i][j][]=max(f[i-][j][],f[i-][j-][])-a[i];
f[i][j][]=max(f[i-][j][],f[i][j][]);
f[i][j][]=max(f[i-][j][],f[i][j][]);
}else{
f[i][j][]=max(f[i-][j][],f[i-][j-][])+*a[i];
f[i][j][]=max(f[i-][j][],f[i-][j-][])-*a[i];
f[i][j][]=max(f[i-][j-][],max(f[i-][j][],f[i][j][]));
f[i][j][]=max(f[i-][j-][],max(f[i-][j][],f[i][j][]));
}

其实挺好想的,考虑一下实际情况就好理解了,1和k的情况单独拿出来转移,因为他们的系数为1和-1

最终答案就是max(f[n][k][2],f[n][k][3])

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define re register
#define int long long
using namespace std;
const int MAXN=3e4+5;
int n,k,a[MAXN],f[MAXN][205][4];
signed main(){
scanf("%lld%lld",&n,&k);
for(re int i=1;i<=n;++i) scanf("%lld",&a[i]);
memset(f,-0x3f,sizeof(f));
for(int i=0;i<=n;++i)
for(int j=0;j<4;++j) f[i][0][j]=0;
for(int i=1;i<=n;++i){
int N=min(i,k);
for(int j=1;j<=N;++j){
if(j==1||j==k){
f[i][j][0]=max(f[i-1][j][0],f[i-1][j-1][2])+a[i];
f[i][j][1]=max(f[i-1][j][1],f[i-1][j-1][3])-a[i];
f[i][j][2]=max(f[i-1][j][2],f[i][j][1]);
f[i][j][3]=max(f[i-1][j][3],f[i][j][0]);
}else{
f[i][j][0]=max(f[i-1][j][0],f[i-1][j-1][2])+2*a[i];
f[i][j][1]=max(f[i-1][j][1],f[i-1][j-1][3])-2*a[i];
f[i][j][2]=max(f[i-1][j-1][2],max(f[i-1][j][2],f[i][j][1]));
f[i][j][3]=max(f[i-1][j-1][3],max(f[i-1][j][3],f[i][j][0]));
}
}
}
printf("%lld\n",max(f[n][k][2],f[n][k][3]));
return 0;
}

csps模拟86异或,取石子,优化题解的更多相关文章

  1. bzoj 1874 取石子游戏 题解 &amp; SG函数初探

    [原题] 1874: [BeiJing2009 WinterCamp]取石子游戏 Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 334  Solved ...

  2. 洛谷P4860 Roy&October之取石子II 题解 博弈论

    题目链接:https://www.luogu.org/problem/P4860 和<P4018 Roy&October之取石子>一样的推导思路,去找循环节. 可以发现:只要不能被 ...

  3. CSPS模拟 86

    看见异或两个字就孩怕 T1 按位? T2 这道异或稍水啊233 貌似可以打表找找规律 emm七种转移,有重复刷表 优化一下? T3 skyh已经接了2杯水了(实际情况他已经ak了) cbx开始抬头傻笑 ...

  4. [CSP-S模拟测试]:异或(数学)

    题目描述 给定$L,R$,我们希望你求出:$$\sum\limits_{i=L}^R\sum\limits_{j=L}^R(i\oplus j)$$其中这里的$\oplus$表示异或运算.答案对$10 ...

  5. [CSP-S模拟测试]:bird(线段树优化DP)

    题目传送门(内部题89) 输入格式 第一行两个数$n$和$k$,分别表示小鸟的只数和$R$装弹时间.接下来$n$行,每行两个数$l,r$表示$n$只小鸟初始时的头和尾的$x$坐标. 输出格式 输出一个 ...

  6. [CSP-S模拟测试]:异或(树状数组+LCA)

    题目传送门(内部题21) 输入格式 第一行一个字符串$str$,表示数据类型.第二行一个正整数$k$,表示集合$K$的大小,保证$k>1$.接下来$k$行每行$k$个数,第$i$行第$j$个数表 ...

  7. csps模拟69chess,array,70木板,打扫卫生题解

    题面:https://www.cnblogs.com/Juve/articles/11663898.html 69: 本以为T2傻逼题结果爆零了...T3原题虽然打的不是正解复杂度但是都不记得做过这道 ...

  8. csp-s模拟测试61砖块, 数字,甜圈题解

    题面:https://www.cnblogs.com/Juve/articles/11626350.html 砖块: 直接模拟即可,map统计被覆盖的次数 #include<iostream&g ...

  9. csp-s模拟测试53u,v,w题解

    题面:https://www.cnblogs.com/Juve/articles/11602450.html u: 用差分优化修改 二维差分:给(x1,y1),(x2,y2)加上s: $d[x1][y ...

随机推荐

  1. 案例2:tab栏切换

    <style> body,ul,li,div{margin:0;padding: 0;} ul{font-size: 0px;} .tab_list{ border: 1px gray s ...

  2. linux 档案 指令(鸟哥私房菜)

    [ls -al] [ls -l --full-time] 显示文件完整的日期格式 [ls] 显示非隐藏档的文件信息 [ls -al] 显示所有文档信心.文档前面的 “”.“”表明该文档是隐藏档.eg. ...

  3. 【转载】API权限设计总结

    本文内容转自:http://blog.csdn.net/initphp/article/details/8636669 API权限设计总结: 最近在做API的权限设计这一块,做一次权限设计的总结. 1 ...

  4. HDU6181-求解次短路-A*或者dijkstra

    (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 题意:传送门  原题目描述在最下面.  次短路裸题. 思路:  在dijstra的过程过维护两个数组变量:\(dis1[],dis2[ ...

  5. Api:temple

    ylbtech-Api: 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部     6.返回顶部   作者:ylbtech出处:http://ylbtech.cnb ...

  6. 牛客练习赛43B Tachibana Kanade Loves Probability

    题目链接:https://ac.nowcoder.com/acm/contest/548/C 题目大意 略 分析 利用快速幂先移到 k1 位,然后开始一个一个取余数. 代码如下 #include &l ...

  7. 剑指offer——18打印从1到最大的n位数

    题目: 输入数字n,按顺序打印出从1到最大的n位十进制数.比如输入3,则打印出1.2.3一直到最大的3位数999. 题解: 注意大数溢出问题,故使用字符串更靠谱 class Solution { pu ...

  8. 剑指offer——16二进制中1的个数

    题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 有可能引起死循环解法: 每次判断最右端是不是1[与 & 1即可],是就cnt++,然后右移一位,直到num为0,结束 ...

  9. SElinux(转)

    转自:http://www.361way.com/rh134-selinux/4653.html RH134小结(四)初识SElinux 2015年8月2日admin发表评论阅读评论   一.SEli ...

  10. 线性可分SVM中线性规划问题的化简

    在网上找了许多关于线性可分SVM化简的过程,但似乎都不是很详细,所以凭借自己的理解去详解了一下. 线性可分SVM的目标是求得一个超平面(其实就是求w和b),在其在对目标样本的划分正确的基础上,使得到该 ...