zoukankan      html  css  js  c++  java
  • 搜索(四分树):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
    ",Solve(n,m,0,0,len,len,len));
    60     }
    61     return 0;    
    62 }
    尽最大的努力,做最好的自己!
  • 相关阅读:
    SpringBoot集成logback.xml日志配置文件找不到错误
    两个List集合如何去重,取交集,并集,差集
    分转元工具类
    Redis(二十九)PHP 使用 Redis
    Redis学习(二十八)Java 使用 Redis
    Redis学习(二十七)Redis 分区
    Redis学习(二十六)Redis 管道技术
    面试题
    Android 自动化测试
    Inner Functions
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5575462.html
Copyright © 2011-2022 走看看