[Gym103960B] Fun with Stones

2024-09-09 08:36
文章标签 fun stones gym103960b

本文主要是介绍[Gym103960B] Fun with Stones,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

并不是多困难或者有趣的题,写sol仅仅是因为觉得好笑()。

题目大意

三堆石子 Nim 游戏,第 i i i 堆石子数量在 [ l i , r i ] [l_i , r_i] [li,ri] 中随机,求先手必胜的概率,对 1 0 9 + 7 10^9+7 109+7 取模。

l i , r i ≤ 1 0 9 l_i , r_i≤10^9 li,ri109

题解

说人话就是求三个数异或起来不为0的概率,很容易想到数位dp,由于只有三个数,硬求就好了。

那么为什么我上面写到 “觉得好笑” 呢。

因为听说有个很高妙的写法十几分钟就可以写完,可我是sb我不会,然后很正经地写了个27类巨大分讨6k数位dp,更好笑的是写完居然一遍过了()。事后知道有高妙写法的我:(iДi) 。

还是大概说一下,先算出异或和为0的方案数最后减一下除以总数即可。区间比较难求那就dp求出范围分别小于 x , y , z x,y,z x,y,z 的然后容斥一下即可。dp具体实现就是 f i , 0 / 1 , 0 / 1 , 0 / 1 f_{i,0/1,0/1,0/1} fi,0/1,0/1,0/1 ,代表现在考虑到第 i i i 位、第一个数是否顶着上界、第二个数是否顶着上界、第三个数是否顶着上界的方案数。转移时分别枚举三个数在这一位上是 0/1,三个数的当前位置分别和上界当前位置比较大小再自己算一下这一位可以从哪些状态转移过来即可。

复杂度也许是 l o g log log 带巨大常数,总之能过。

Code

写得很蠢,但是因为很好笑所以还是贴上来吧,就当看个乐子。

#include<bits/stdc++.h>
using namespace std;const int N=35,mod=1e9+7;int l1,r1,l2,r2,l3,r3,ans,f[N][2][2][2];int solve(int x,int a,int a1,int b,int b1,int c,int c1){int res=0;for(int i=a;i<=a1;i++)for(int j=b;j<=b1;j++)for(int k=c;k<=c1;k++)res=(res+f[x][i][j][k])%mod;return res;
}int work(int a,int b,int c){memset(f,0,sizeof(f));f[32][1][1][1]=1;for(int i=31,x,y,z;i>=0;i--){x=((a>>i)&1),y=((b>>i)&1),z=((c>>i)&1);for(int a1=0;a1<=1;a1++)for(int b1=0;b1<=1;b1++)for(int c1=0;c1<=1;c1++){if((a1^b1^c1)!=0) continue;if(a1<x){if(b1<y){if(c1<z) f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,1,0,1,0,1))%mod;else if(c1==z){f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,1,0,1,0,0))%mod;f[i][0][0][1]=(f[i][0][0][1]+solve(i+1,0,1,0,1,1,1))%mod;}else f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,1,0,1,0,0))%mod;}else if(b1==y){if(c1<z){f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,1,0,0,0,1))%mod;f[i][0][1][0]=(f[i][0][1][0]+solve(i+1,0,1,1,1,0,1))%mod;}else if(c1==z){f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,1,0,0,0,0))%mod;f[i][0][1][0]=(f[i][0][1][0]+solve(i+1,0,1,1,1,0,0))%mod;f[i][0][0][1]=(f[i][0][0][1]+solve(i+1,0,1,0,0,1,1))%mod;f[i][0][1][1]=(f[i][0][1][1]+solve(i+1,0,1,1,1,1,1))%mod;}else{f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,1,0,0,0,0))%mod;f[i][0][1][0]=(f[i][0][1][0]+solve(i+1,0,1,1,1,0,0))%mod;}}else{if(c1<z) f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,1,0,0,0,1))%mod;else if(c1==z){f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,1,0,0,0,0))%mod;f[i][0][0][1]=(f[i][0][0][1]+solve(i+1,0,1,0,0,1,1))%mod;}else f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,1,0,0,0,0))%mod;}}else if(a1==x){if(b1<y){if(c1<z){f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,1,0,1))%mod;f[i][1][0][0]=(f[i][1][0][0]+solve(i+1,1,1,0,1,0,1))%mod;}else if(c1==z){f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,1,0,0))%mod;f[i][0][0][1]=(f[i][0][0][1]+solve(i+1,0,0,0,1,1,1))%mod;f[i][1][0][0]=(f[i][1][0][0]+solve(i+1,1,1,0,1,0,0))%mod;f[i][1][0][1]=(f[i][1][0][1]+solve(i+1,1,1,0,1,1,1))%mod;}else{f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,1,0,0))%mod;f[i][1][0][0]=(f[i][1][0][0]+solve(i+1,1,1,0,1,0,0))%mod;}}else if(b1==y){if(c1<z){f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,0,0,1))%mod;f[i][0][1][0]=(f[i][0][1][0]+solve(i+1,0,0,1,1,0,1))%mod;f[i][1][0][0]=(f[i][1][0][0]+solve(i+1,1,1,0,0,0,1))%mod;f[i][1][1][0]=(f[i][1][1][0]+solve(i+1,1,1,1,1,0,1))%mod;}else if(c1==z){f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,0,0,0))%mod;f[i][0][1][0]=(f[i][0][1][0]+solve(i+1,0,0,1,1,0,0))%mod;f[i][0][0][1]=(f[i][0][0][1]+solve(i+1,0,0,0,0,1,1))%mod;f[i][0][1][1]=(f[i][0][1][1]+solve(i+1,0,0,1,1,1,1))%mod;f[i][1][0][0]=(f[i][1][0][0]+solve(i+1,1,1,0,0,0,0))%mod;f[i][1][1][0]=(f[i][1][1][0]+solve(i+1,1,1,1,1,0,0))%mod;f[i][1][0][1]=(f[i][1][0][1]+solve(i+1,1,1,0,0,1,1))%mod;f[i][1][1][1]=(f[i][1][1][1]+solve(i+1,1,1,1,1,1,1))%mod;}else{f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,0,0,0))%mod;f[i][0][1][0]=(f[i][0][1][0]+solve(i+1,0,0,1,1,0,0))%mod;f[i][1][0][0]=(f[i][1][0][0]+solve(i+1,1,1,0,0,0,0))%mod;f[i][1][1][0]=(f[i][1][1][0]+solve(i+1,1,1,1,1,0,0))%mod;}}else{if(c1<z){f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,0,0,1))%mod;f[i][1][0][0]=(f[i][1][0][0]+solve(i+1,1,1,0,0,0,1))%mod;}else if(c1==z){f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,0,0,0))%mod;f[i][0][0][1]=(f[i][0][0][1]+solve(i+1,0,0,0,0,1,1))%mod;f[i][1][0][0]=(f[i][1][0][0]+solve(i+1,1,1,0,0,0,0))%mod;f[i][1][0][1]=(f[i][1][0][1]+solve(i+1,1,1,0,0,1,1))%mod;}else{f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,0,0,0))%mod;f[i][1][0][0]=(f[i][1][0][0]+solve(i+1,1,1,0,0,0,0))%mod;}}}else{if(b1<y){if(c1<z) f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,1,0,1))%mod;else if(c1==z){f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,1,0,0))%mod;f[i][0][0][1]=(f[i][0][0][1]+solve(i+1,0,0,0,1,1,1))%mod;}else f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,1,0,0))%mod;}else if(b1==y){if(c1<z){f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,0,0,1))%mod;f[i][0][1][0]=(f[i][0][1][0]+solve(i+1,0,0,1,1,0,1))%mod;}else if(c1==z){f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,0,0,0))%mod;f[i][0][1][0]=(f[i][0][1][0]+solve(i+1,0,0,1,1,0,0))%mod;f[i][0][0][1]=(f[i][0][0][1]+solve(i+1,0,0,0,0,1,1))%mod;f[i][0][1][1]=(f[i][0][1][1]+solve(i+1,0,0,1,1,1,1))%mod;}else{f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,0,0,0))%mod;f[i][0][1][0]=(f[i][0][1][0]+solve(i+1,0,0,1,1,0,0))%mod;}}else{if(c1<z) f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,0,0,1))%mod;else if(c1==z){f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,0,0,0))%mod;f[i][0][0][1]=(f[i][0][0][1]+solve(i+1,0,0,0,0,1,1))%mod;}else f[i][0][0][0]=(f[i][0][0][0]+solve(i+1,0,0,0,0,0,0))%mod;}}}}return solve(0,0,1,0,1,0,1);
}int qpow(int x,int y){int res=1;for(;y;y>>=1,x=1ll*x*x%mod)if(y&1) res=1ll*res*x%mod;return res;
}int main(){scanf("%d%d%d%d%d%d",&l1,&r1,&l2,&r2,&l3,&r3);ans=((work(r1,r2,r3)-work(l1-1,r2,r3)-work(r1,l2-1,r3)-work(r1,r2,l3-1)+work(l1-1,l2-1,r3)+work(l1-1,r2,l3-1)+work(r1,l2-1,l3-1)-work(l1-1,l2-1,l3-1))%mod+mod)%mod;int az=1ll*(r1-l1+1)*(r2-l2+1)%mod*(r3-l3+1)%mod;printf("%d",1ll*(az-ans+mod)%mod*qpow(az,mod-2)%mod);return 0;
}

看这幽默的代码不去做大模拟真的可惜了。

这篇关于[Gym103960B] Fun with Stones的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1150660

相关文章

得到验证码fun

{得到验证码} function  TFrmLogin.GetVerfCode():string; var    i,iLen : integer;    sNum : string;    t:TSIzeF; begin   Randomize;   sNum := Format('%.4d', [Random(10000)]);   t.cx :=48;

【论文分享】GPU Memory Exploitation for Fun and Profit 24‘USENIX

目录 AbstractIntroductionResponsible disclosure BackgroundGPU BasicsGPU architectureGPU virtual memory management GPU Programming and ExecutionGPU programming modelGPU kernelDevice function NVIDIA

Fun with pointer!

int x=1; //x的地址为50 语句p*pxint x=1; const int *p =&x;50 可以修改 int y=2;p=&y,此时p和*p都变1  不能修改可以改变。x=2,此时*p=2,但p不变const int x=1;const int *p=&x;50 不可修改1 不可修改不可修改const int x=1;int *p=&x;出错  只能常量指针才可以指向常量

HDU 1896 Stones (Priority_queue)

【题目链接】:click here~~ 【题目大意】: 就是说在一条直线道路上有n个石头,往前走,遇到一个数一个,如果遇到的是第奇数个那就把这个石头往前扔距离dis[i], 如果是第偶数个,就放置不管。 问人走到最后一个石头的位置距原地多远(遇到的最后一个石头距离出发点的位置是多少)。 【思路】模拟即可,遇到第奇数个石头,就将其加上dis[i],放回到优先队列(priority_queue)

HDU4737A Bit Fun

题目:HDU4737A Bit Fun 题目大意:给出N个数,然后问里面有多少个子串,对于每个子串做或运算的结果小于m。 解题思路:这题测试数据比较水,暴力就可以过。正解:把每个数都用二进制存起来,然后一开始head和tail都指向1.每次tail都++,对于每个tail求出离他最远的head。然后求和一下每个tail满足条件的子串。注意当head到tail的和超过m的时候,就要将

Algorithm学习笔记 --- Function Run Fun

总时间限制:  1000ms  内存限制:  65536kB 描述 We all love recursion! Don't we? Consider a three-parameter recursive function w(a, b, c): if a <= 0 or b <= 0 or c <= 0, then w(a, b, c) returns: 1 if a

你才是自己生活的主宰者!——Are we having fun yet

人各有不同,不同的人适合做不同的事。某人喜欢做特定的某件事,这并不意味着你也要去喜欢。判断一件事情是否该去做,不能只凭它能否带来物质利益等,而应看此事是否能够带给我们乐趣并使我们获得满足感。你的工作带给你自豪感和满足感了吗?你是在执行“应该”指令,还是依照“想做”的意愿呢? we are all very different and different things appeal to each

codeforces 372C Watching Fireworks is Fun 单调队列优化dp

题意:一个城镇有n个区域,从左到右1-n,每个区域之间距离1个单位距离。节日中有m个烟火要放,给定放的地点a[ i ]、时间t[ i ] ,如 果你当时在区域x,那么你可以获得b[ i ] - | a[ i ] - x |的happiness 。你每个单位时间可以移动不超过d个单位距离,你的初始位置是任意 的,求你通过移动能获取到的最大的happiness值。 思路: 首先设dp[i]

Codeforces #248 (Div. 2) B. Kuriyama Mirai's Stones

题意是:给出一个数组,之后给出l,r然你输出下标l和r之间所有数的和 开始想到暴力了,但是看到n最大为10的5次方,想到会超时吧 然后想到了树状数组,但是只是知道有这个概念,并不知道怎么实现 然后就看了别人的代码,发现暴力完全可以 理由是只需排序O(nlogn)算法,而log(10^5)是很小的。。。 思维固化就跪了 代码如下: #include <cstdio>#includ

poj-1579-Function Run Fun

#include<stdio.h> #include<string.h> int d[21][21][21]; int w(int a,int b,int c) {  if(a<=0||b<=0||c<=0)   return 1;  else if(a>20||b>20||c>20)   return d[20][20][20]=w(20,20,20);/*数组用