[java线段树]2015上海邀请赛 D Doom

题意:n个数 m个询问

每个询问[l, r]的和, 再把[l, r]之间所有的数变为平方(模为9223372034707292160LL)

很明显的线段树

看到这个模(LLONG_MAX为9223372036854775807) 很明显平方时会爆LL

很容易发现所有数平方模了几次之后值就不再改变了 而且这个“几次”相当小 因此直接暴力搞就好了

    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        BigInteger a=BigInteger.valueOf(2);     //   这里看的是2的平方
        Long b=9223372034707292160L;
        BigInteger mod=new BigInteger(b.toString());
        for(int i=1;i<=40;i++)
        {
            a=a.multiply(a).mod(mod);
            System.out.println(i + ":" + a);     //  平方i次之后的值
        }
    }

  1 import java.io.*;
  2 import java.util.*;
  3 import java.math.*;
  4 import java.nio.charset.StandardCharsets;
  5
  6 public class Main
  7 {
  8     static BigInteger li=BigInteger.ZERO;
  9     static Long b=9223372034707292160L;
 10     static BigInteger mod=new BigInteger(b.toString());
 11     static BigInteger[] sum=new BigInteger[200005];
 12     static boolean[] num=new boolean[200005];
 13     static InputReader in = new InputReader();
 14     public static void pushup(int rt)
 15     {
 16         sum[rt]=(sum[rt*2].add(sum[rt*2+1])).mod(mod);
 17         num[rt]=num[rt*2]&num[rt*2+1];
 18     }
 19     public static void build(int l, int r, int rt)
 20     {
 21         if(l==r)
 22         {
 23             sum[rt]=in.nextBigInteger();
 24             num[rt]=false;
 25             return ;
 26         }
 27         int m=(l+r)/2;
 28         build(l, m, rt*2);
 29         build(m+1, r, rt*2+1);
 30         pushup(rt);
 31     }
 32     public static BigInteger query(int L, int R, int l, int r, int rt)
 33     {
 34         if(L<=l && r<=R)
 35             return sum[rt];
 36         int m=(l+r)/2;
 37         BigInteger ret=li;
 38         if(L<=m)
 39             ret=ret.add(query(L, R, l, m, rt*2)).mod(mod);
 40         if(R>m)
 41             ret=ret.add(query(L, R, m+1, r, rt*2+1)).mod(mod);
 42         return ret.mod(mod);
 43     }
 44     public static void update(int p, int l, int r, int rt)
 45     {
 46         if(l==r)
 47         {
 48             BigInteger cur=(sum[rt].multiply(sum[rt])).mod(mod);
 49             if(sum[rt].equals(cur))
 50                 num[rt]=true;
 51             sum[rt]=cur;
 52             return ;
 53         }
 54         int m=(l+r)/2;
 55         if(p<=m)
 56             update(p, l, m, rt*2);
 57         else
 58             update(p, m+1, r, rt*2+1);
 59         pushup(rt);
 60     }
 61     static int n;
 62     public static void update(int L, int R, int l, int r, int rt)
 63     {
 64         if(L<=l && r<=R)
 65         {
 66             if(num[rt])
 67                 return ;
 68             if(l==r)
 69                 update(l, 1, n, 1);
 70             else
 71             {
 72                 int mm=(l+r)/2;
 73                 update(L, R, l, mm, rt<<1);
 74                 update(L, R, mm+1, r, rt<<1|1);
 75             }
 76
 77             return ;
 78         }
 79         int m=(l+r)/2;
 80         if(L<=m)
 81             update(L, R, l, m, rt*2);
 82         if(R>m)
 83             update(L, R, m+1, r, rt*2+1);
 84         pushup(rt);
 85     }
 86     public static void main(String[] args)
 87     {
 88         int t, ca=1;
 89         t=in.nextInt();
 90         while((t--)!=0)
 91         {
 92             n=in.nextInt();
 93             int m=in.nextInt();
 94             build(1, n, 1);
 95             System.out.println("Case #" + ca + ":");
 96             ca++;
 97             BigInteger ans=li;
 98             while((m--)!=0)
 99             {
100                 int l, r;
101                 l=in.nextInt();
102                 r=in.nextInt();
103                 ans=ans.add(query(l, r, 1, n, 1)).mod(mod);
104                 System.out.println(ans);
105                 update(l, r, 1, n, 1);
106             }
107         }
108     }
109 }

时间: 2024-10-11 23:29:16

[java线段树]2015上海邀请赛 D Doom的相关文章

java,线段树

线段树: 你可以理解成:线段组成的树,很多人问我,线段树到底有何用处,其实这个问题,你可以自己去刷题,然后总结出检验. 线段的具体理解,我看到一篇很好的博客,我就不展开了.博客地址:https://blog.csdn.net/iwts_24/article/details/81484561 基础题目: hdu1166敌兵布阵: 如果我们没有学过线段树,我们肯定是用模拟+暴力的方法. 模拟+暴力的方法代码: package Combat.com; import java.math.BigInteg

UESTC_秋实大哥与线段树 2015 UESTC Training for Data Structures&lt;Problem M&gt;

M - 秋实大哥与线段树 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status “学习本无底,前进莫徬徨.” 秋实大哥对一旁玩手机的学弟说道. 秋实大哥是一个爱学习的人,今天他刚刚学习了线段树这个数据结构. 为了检验自己的掌握程度,秋实大哥给自己出了一个题,同时邀请大家一起来作. 秋实大哥的题目要求你维护一个序列,支持两种操作:一种是修改某一个元素的值:一

2015上海邀请赛

这次上海邀请赛差一点就能拿到牌子了,好可惜..... Game回来写了下,刚开始把重链写成了最大权子树,无限WA,然后一直在调..... 发现我一旦提交上去错了就始终在找程序BUG,从来没想过是不是思路哪里错掉了....其实这种交上去WA之后应该先去找思路上的错误,而不是怀疑题目有陷阱什么的... #include<stdio.h> #include<string.h> #include<vector> #include<list> #include<

Java线段树

线段树不是完全二叉树,是平衡二叉树 堆也是平衡二叉树 堆满二叉树: h层,一共有2^h-1个节点(大约是2^h) 最后一层(h-1层)有2^(h-1)个节点 最后一层的节点数大致等于前面所有层节点之和 如果区间有n个元素,数组表示需要4n的空间 不考虑添加元素,使用4n的静态空间即可 原文地址:https://www.cnblogs.com/sunliyuan/p/10720167.html

[java]2015上海邀请赛 B Base64

题意: 给n和一个字符串(可以有空格) 求字符串编码n次后的字符串 编码方式:字符串的每个字符转化成ASCII码, ASCII码转化成8位2进制,    将二进制数分割成6位为一组的(不够的补0), 再变成十进制数 依次按照以下方式变成字母 转化成字母后, 若长度不是4的整数倍, 在字符串后面补= 举个例子, The的ASCII码分别为84,104,101 转成8位2进制为01010100,01101000,01100101 分割成6位的为010101,000110,100001,100101

HDU 5242 GAME 2015上海邀请赛G题

题目链接:hdu 5242 题意:给定一颗以1号节点为根节点的有向树,每个节点有一个权值,问从1号节点出发k次,能到达的所有节点的和的最大值. 思路:贪心的把树的链按照权值和从大到小剖分成若干条链(过程可以根据上交书上的熟练剖分模版做细小改动),然后根据每条链的权值排序取最大的k个就是答案. 代码: #include <cstdio> #include <cmath> #include <iostream> #include <cstring> #inclu

hdu 1754 I Hate It(线段树/树状数组)

I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 48790    Accepted Submission(s): 19111 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师

[POI 2001+2014acm上海邀请赛]Gold Mine/Beam Cannon 线段树+扫描线

Description Byteman, one of the most deserving employee of The Goldmine of Byteland, is about to retire by the end of the year. The Goldmine management would like to reward him in acknowledgment of his conscientious work. As a reward Byteman may rece

hdu 5475 模拟计算器乘除 (2015上海网赛F题 线段树)

给出有多少次操作 和MOD 初始值为1 操作1 y 表示乘上y操作2 y 表示除以第 y次操作乘的那个数 线段树的叶子结点i 表示 第i次操作乘的数 将1替换成y遇到操作2 就把第i个结点的值 替换成1利用线段树的性质,对整个1~n的区间进行维护,每次输出sum[1]的值即可 Sample Input110 10000000001 22 11 21 102 32 41 61 71 122 7 Sample OutputCase #1:2122010164250484 1 # include <i