搜索(四分树):BZOJ 4513 [SDOI2016 Round1] 储能表

4513: [Sdoi2016]储能表

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 395  Solved: 213
[Submit][Status][Discuss]

Description

有一个 n 行 m 列的表格,行从 0 到 n−1 编号,列从 0 到 m−1 编号。每个格子都储存着能量。最初,第 i 行第 j 列的格子储存着 (i xor j) 点能量。所以,整个表格储存的总能量是,

随着时间的推移,格子中的能量会渐渐减少。一个时间单位,每个格子中的能量都会减少 1。显然,一个格子的能量减少到 0 之后就不会再减少了。

也就是说,k 个时间单位后,整个表格储存的总能量是,

给出一个表格,求 k 个时间单位后它储存的总能量。

由于总能量可能较大,输出时对 p 取模。

Input

第一行一个整数 T,表示数据组数。接下来 T 行,每行四个整数 n、m、k、p。

Output

共 T 行,每行一个数,表示总能量对 p 取模后的结果

Sample Input

3
2 2 0 100
3 3 0 100
3 3 1 100

Sample Output

2
12
6

HINT

T=5000,n≤10^18,m≤10^18,k≤10^18,p≤10^9

  找规律的方法过的。

  思路在程序中很清楚,用四分树搜索。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 typedef long long LL;
 6
 7 LL n,m,k,mod,len;
 8 LL Max(LL a,LL b){
 9     return a>b?a:b;
10 }
11
12 LL Mul(LL a,LL b){
13     LL ret=0;
14     a%=mod;b%=mod;
15     while(a){
16         if(a&1)ret=(ret+b)%mod;
17         a>>=1;b<<=1;
18     }
19     return ret;
20 }
21
22 LL Calc1(LL h,LL tot){
23     LL t=h+tot-1,ret=0;
24     h=Max(1,h-k);t-=k;
25     if(h>t)return 0;
26     if((h+t)&1) ret=Mul(Mul((h+t),(t-h+1)/2),tot);
27     else ret=Mul(Mul((t-h+1),((h+t)/2)),tot);
28     return ret;
29 }
30
31 LL Calc2(LL h,LL t,LL lb){
32     LL ret=0;
33     h=Max(1ll,h-k);t-=k;
34     if(h>t)return 0;
35     if((h+t)&1) ret=Mul(Mul((h+t),(t-h+1)/2),lb);
36     else ret=Mul(Mul((t-h+1),((h+t)/2)),lb);
37     return ret;
38 }
39
40 LL Solve(LL qa,LL qb,LL x1,LL y1,LL x2,LL y2,LL l){
41     if(x1<y1){swap(qa,qb);swap(x1,y1);swap(x2,y2);}
42     if(qa>=x2&&qb>=y2){return Calc1(x1^y1,l);}
43     else if(qa>=x2){return Calc2(x1^y1,(x1^y1)+l-1,qb-y1);}
44     else if(qb>=y2){return Calc2(x1^y1,(x1^y1)+l-1,qa-x1);}
45     LL mx=(x1+x2)>>1,my=(y1+y2)>>1,ret=0;
46     if(x1<qa&&y1<qb)ret=(ret+Solve(qa,qb,x1,y1,mx,my,l>>1))%mod;
47     if(mx<qa&&y1<qb)ret=(ret+Solve(qa,qb,mx,y1,x2,my,l>>1))%mod;
48     if(x1<qa&&my<qb)ret=(ret+Solve(qa,qb,x1,my,mx,y2,l>>1))%mod;
49     if(mx<qa&&my<qb)ret=(ret+Solve(qa,qb,mx,my,x2,y2,l>>1))%mod;
50     return ret;
51 }
52 int main(){
53     int T;
54     scanf("%d",&T);
55     while(T--){
56         scanf("%lld%lld%lld%lld",&n,&m,&k,&mod);
57         if(n<m)swap(n,m);len=1;
58         while(len<n)len<<=1;
59         printf("%lld\n",Solve(n,m,0,0,len,len,len));
60     }
61     return 0;
62 }
时间: 2024-10-12 20:14:13

搜索(四分树):BZOJ 4513 [SDOI2016 Round1] 储能表的相关文章

BZOJ 4513: [Sdoi2016]储能表

Description 求\(\sum_{i=0}^{n-1}\sum_{i=0}^{n-1}max\{i\)^\(j-k,0\}\) \(n,m\leqslant 10^{18},k\leqslant 10^9\) Solution 数位DP. 我好弱啊qwq... \(f[i][na][nb][nc]\)表示枚举到第\(i\)位,是否卡\(n\)上界,是否卡\(m\)上界,是否卡\(k\)下界. 枚举\(i\)这一位01,\(j\)这一位01,枚举上一个状态,判断一下合法,计算转移后的状态,

loj2030 「SDOI2016」储能表

ref ref 一个点就是一个数对 \((x,y)\). 记状态 \(f[i][1/0][1/0][1/0]\) 和 \(g[i][1/0][1/0][1/0]\),其中三个 \(1/0\) 取值分别代表"\(x\) 在前 \(i\) 位卡满 \(n\)(的前 \(i\) 位)/小于它"."\(y\) 在前 \(i\) 位卡满 \(m\)(的前 \(i\) 位)/小于它"."\(k_{current}\) 在前 \(i\) 位卡满 \(k\)(的前 \(i

4513: [Sdoi2016]储能表

4513: [Sdoi2016]储能表 链接 分析: 数位dp. 横坐标和纵坐标一起数位dp,分别记录当前横纵坐标中这一位是否受n或m的限制,在记录一维表示当前是否已经大于k了. 然后需要两个数组记录答案,分别记录个数和答案的和. 语意不清了...看代码吧.. 代码: #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<iostream>

UVa 297 Quadtrees(四分树)

题意  可以用一个四分图表示一32*32的黑白图像   求两个四分树对应图像相加所得图形黑色部分有多少像素 直接用一个32*32的矩阵表示图  黑色为非0白色为0  递归建图   最后有多少个非零就是答案了 #include<cstdio> #include<cstring> using namespace std; const int L = 32, N = 1050; char s[N]; int ans[L][L], cnt; void draw(char *s, int &

UVA - 297 Quadtrees (四分树)

题意:求两棵四分树合并之后黑色像素的个数. 分析:边建树边统计. #include<cstdio> #include<cstring> #include<cstdlib> #include<cctype> #include<cmath> #include<iostream> #include<sstream> #include<iterator> #include<algorithm> #inclu

[SDOI2016 Round1] 数字配对

COGS 2221. [SDOI2016 Round1] 数字配对 http://www.cogs.pro/cogs/problem/problem.php?pid=2221 ★★★   输入文件:menci_pair.in   输出文件:menci_pair.out   简单对比时间限制:1 s   内存限制:128 MB [题目描述] 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 aiaj 是一个质数,那么这两

UVa 806 四分树

题意: 分析: 类似UVa 297, 模拟四分树四分的过程, 就是记录一个左上角, 记录宽度wideth, 然后每次w/2这样递归下去. 注意全黑是输出0, 不是输出1234. 1 #include <bits/stdc++.h> 2 using namespace std; 3 // 1 2 4 // 3 4 5 const int base5[8] = {1,5,25,125,625,3125,15625,78125}; 6 int n; 7 string G[70]; 8 vector&

UVa 297.Quadtrees【非二叉树之四分树】【7月31】

Quadtrees A quadtree is a representation format used to encode images. The fundamental idea behind the quadtree is that any image can be split into four quadrants. Each quadrant may again be split in four sub quadrants, etc. In the quadtree, the imag

LintCode 单词搜索Ⅱ 字典树

今天做了道有意思的题目,题目要解出来不难,但看到他的提示 发现这道题我一开始并没有用到字典树 然后就使用字典树+DFS写了一遍,也算是巩固下字典树的相关知识 题目:原题地址 给出一个由小写字母组成的矩阵和一个字典.找出所有同时在字典和矩阵中出现的单词.一个单词可以从矩阵中的任意位置开始,可以向左/右/上/下四个相邻方向移动. 样例 给出矩阵: doafagaidcan 和字典: {"dog", "dad", "dgdg", "can&q