4513: [Sdoi2016] Energy meter time limit:10 Sec Memory limit:128 MB
submit:395 solved:213
[Submit] [Status] [Discuss] Description
There is an n-row m-column table with rows from 0 to n−1 numbered, and columns numbered from 0 to m−1. Each lattice stores energy. Initially, the lattice in row I, Column J, stores (I xor J) Point Energy. So, the total energy stored in the entire table is,
As time goes on, the energy in the lattice will gradually decrease. One time unit, the energy in each grid will be reduced by 1. Obviously, the energy of a lattice is reduced to less than 0. That is, after k time units, the total energy stored in the entire table is, given a table, to find the total amount of energy stored in K time units. Because the total amount of the total can be large, the output of P modulo. Input
The first line is an integer T that represents the number of data groups. Next T line, four integers per line n, m, K, p.
Output
A total of T-lines, one number per line, indicating the result of the total energy after P modulo
Sample Input3
2 2 0 100
3 3 0 100
3 3 1Sample Output2
12
6HINT
T=5000,n≤10^18,m≤10^18,k≤10^18,p≤10^9
Looking for a regular way of doing it.
The idea in the program is very clear, with a four-point tree search.
1#include <iostream>2#include <cstring>3#include <cstdio>4 using namespacestd;5typedefLong LongLL;6 7 LL N,m,k,mod,len;8 ll Max (ll A,ll b) {9 returnA>b?a:b;Ten } One A ll Mul (ll A,ll b) { -LL ret=0; -a%=mod;b%=MoD; the while(a) { - if(a&1) ret= (ret+b)%MoD; -a>>=1; b<<=1; - } + returnret; - } + A ll Calc1 (ll h,ll tot) { atLL t=h+tot-1, ret=0; -H=max (1, h-k); t-=K; - if(h>t)return 0; - if((h+t) &1) Ret=mul (Mul (h+t), (t-h+1)/2), tot); - ElseRet=mul (Mul (t-h+1), ((h+t)/2) ), tot); - returnret; in } - to ll CALC2 (ll h,ll t,ll lb) { +LL ret=0; -H=max (1ll,h-k); t-=K; the if(h>t)return 0; * if((h+t) &1) Ret=mul (Mul (h+t), (t-h+1)/2), LB); $ ElseRet=mul (Mul (t-h+1), ((h+t)/2) ), lb);Panax Notoginseng returnret; - } the + ll Solve (ll qa,ll qb,ll x1,ll y1,ll x2,ll y2,ll l) { A if(x1<y1) {swap (QA,QB); swap (x1,y1); swap (x2,y2);} the if(Qa>=x2&&qb>=y2) {returnCalc1 (x1^y1,l);} + Else if(QA>=X2) {returnCALC2 (X1^y1, (x1^y1) +l-1, qb-y1);} - Else if(Qb>=y2) {returnCALC2 (X1^y1, (x1^y1) +l-1, qa-x1);} $LL mx= (x1+x2) >>1, my= (y1+y2) >>1, ret=0; $ if(X1<QA&&Y1<QB) ret= (Ret+solve (qa,qb,x1,y1,mx,my,l>>1))%MoD; - if(MX<QA&&Y1<QB) ret= (Ret+solve (qa,qb,mx,y1,x2,my,l>>1))%MoD; - if(X1<QA&&MY<QB) ret= (Ret+solve (qa,qb,x1,my,mx,y2,l>>1))%MoD; the if(MX<QA&&MY<QB) ret= (Ret+solve (qa,qb,mx,my,x2,y2,l>>1))%MoD; - returnret;Wuyi } the intMain () { - intT; Wuscanf"%d",&T); - while(t--){ Aboutscanf"%lld%lld%lld%lld",&n,&m,&k,&MoD); $ if(n<m) swap (n,m); len=1; - while(len<n) len<<=1; -printf"%lld\n", Solve (N,m,0,0, Len,len,len)); - } A return 0; +}
Search (four-point tree): Bzoj 4513 [SDOI2016 Round1] Energy meter