hdu 5239 Doom

题意:给n个数,每次查询[l,r]的和,然后[l,r]之间的数都会由ai变为ai^2,开始计数器为0,每次在上一次的基础上,为计数器+sum[l,r],答案%9223372034707292160

分析:猜想一个数的平方%p应该会很快进入静止,即ai^2%p=ai,这样这个数就不会更新,用java跑了一发,发现最多更新29次,其实这个无所谓,猜想到这个性质就可以了,然后就是解决下一个问题,mod^2很大,long long也存不下,解决了这个问题,我想剩下的就很简单了,a*a=a个a相加,使用类似于快速幂的形式,求a个a相加并对mod取模的值,用一个lay[rt]表示该节点代表的子树不会被更新,这样就Ok了,裸的线段树

#include<bits/stdc++.h>
#define mmid int mid=(l+r)>>1
#define lson rt*2
#define rson rt*2+1
using namespace std;
typedef long long ll;
const ll mod=9223372034707292160LL;
const int maxn=1e5+5;
ll sum[maxn<<2];
bool lay[maxn<<2];
int ql,qr;
inline bool isdight(char c){return c>=‘0‘&&c<=‘9‘;}

void read(ll &res){
    char c=getchar();
    res=0;
    while(!isdight(c))c=getchar();
    while(isdight(c))res=res*10+c-‘0‘,c=getchar();
}

void read(int &res){
    char c=getchar();
    res=0;
    while(!isdight(c))c=getchar();
    while(isdight(c))res=res*10+c-‘0‘,c=getchar();
}

inline void Mod(ll &x){if(x>=mod)x%=mod;}

void build(int rt,int l,int r){
    lay[rt]=0;
    if(l==r){
        read(sum[rt]);//scanf("%lld",sum+rt);
        return ;
    }
    mmid;
    build(lson,l,mid);
    build(rson,mid+1,r);
    sum[rt]=(sum[lson]+sum[rson]);Mod(sum[rt]);
}

ll pow_add(ll a){
    ll res=0,t=a,k=a;
    while(k){
        if(k&1)res=(t+res),Mod(res);
        t=(t+t);Mod(t);
        k=k>>1;
    }
    return res;
}

ll query(int rt,int l,int r){
    if(ql<=l&&qr>=r)return sum[rt];
    mmid;
    ll res=0;
    if(ql<=mid)res=(res+query(lson,l,mid)),Mod(res);
    if(qr>mid)res=(res+query(rson,mid+1,r)),Mod(res);
    return res;
}

void modify(int rt,int l,int r){

    if(lay[rt])return ;
    if(l==r){
        ll t=pow_add(sum[rt]);
        if(t==sum[rt])lay[rt]=1;
        else sum[rt]=t;
        return ;
    }
    mmid;
    if(ql<=mid&&!lay[lson])modify(lson,l,mid);
    if(qr>mid&&!lay[rson])modify(rson,mid+1,r);
    lay[rt]=(lay[lson]|lay[rson]);
    sum[rt]=(sum[lson]+sum[rson]);Mod(sum[rt]);
}

int main(){

    int t,n,q,cas=1,l,r;
    read(t);
    while(t--){
        read(n);read(q);
        build(1,1,n);
        printf("Case #%d:\n",cas++);
        ll s=0;
        while(q--){
            read(ql);read(qr);
            s=(s+query(1,1,n));Mod(s);
            printf("%lld\n",s);
            modify(1,1,n);
        }
    }
    return 0;
}

  

时间: 2024-12-08 07:56:47

hdu 5239 Doom的相关文章

hdu 5239 Doom(线段树)

Doom Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 1401    Accepted Submission(s): 368 Problem Description THE END IS COMINGGGGGG! Mike has got stuck on a mystery machine. If he cannot solv

HDU 5239 上海大都会 D题(线段树+数论)

打表,发现规律是存在一定次数(较小)后,会出现a=(a*a)%p.可以明显地发现本题与线段树有关.设置标记flag,记录本段内的数是否均已a=a*a%p.若是,则不需更新,否则更新有叶子结点,再pushup. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define LL unsigned long long using namespace st

HDU5239

http://acm.hdu.edu.cn/showproblem.php?pid=5239 Doom Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 722    Accepted Submission(s): 181 Problem Description THE END IS COMINGGGGGG! Mike has got

上海邀请赛 补题中

比赛的时候就出了5题,赛后发现其实很多题可以写,不知道为啥赛时这么逗比加坑队友,过两天做个总结 5236 Article 29.45%(134/455) 5237 Base64 41.67%(175/420)   5238 Calculator 43.85%(82/187) 5239 Doom 23.67%(138/583) 5240 Exam 50.61%(249/492) 5241 Friends 48.86%(215/440) 5242 Game 29.91%(195/652) 5243

hdu 1290 献给杭电五十周年校庆的礼物

献给杭电五十周年校庆的礼物 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7236    Accepted Submission(s): 3936 Problem Description 或许你曾经牢骚满腹 或许你依然心怀忧伤 或许你近在咫尺 或许你我天各一方 对于每一个学子 母校 永远航行在 生命的海洋 今年是我们杭电建校五十周年,

HDU 3128 What is the air speed velocity…(数学)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3128 Problem Description What is the air speed velocity- -of a fully laden swallow? This fearful question was posed to the intrepid band of Grail searchers.Their response of "African or European?" w

HDU#1402. A&#215;B

A * B Problem Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 25361    Accepted Submission(s): 6524 Problem Description Calculate A * B. Input Each line will contain two integers A and B. P

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include