您的位置:首页 > 编程语言 > Java开发

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

2015-05-26 01:43 417 查看
题意: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次之后的值
}
}


#include <bits/stdc++.h>
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1

typedef __int128 LL;
const LL mod=9223372034707292160;
const int N=1e5+5;
LL sum[N<<3];
bool num[N<<3];
template <class T>
bool read(T &ret){char c;int sgn;if(c=getchar(),c==EOF)return 0;while(c!='-' && (c<'0' || c>'9')) c = getchar();sgn = (c == '-') ? -1 : 1;ret = (c == '-') ? 0 : (c - '0');while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');ret *= sgn;return 1;}
template <class T>
void out(T x){if(x<0){putchar('-');x=-x;}if(x>9)out(x/10);putchar(x%10+'0');}
void pushup(int rt)
{
sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%mod;
num[rt]=num[rt<<1]&num[rt<<1|1];
}
void build(int l, int r, int rt)
{
if(l==r)
{
//        scanf("%I64d", &sum[rt]);
read(sum[rt]);
num[rt]=0;
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
LL query(int L, int R, int l, int r, int rt)
{
if(L<=l && r<=R)
return sum[rt];
int m=(l+r)>>1;
LL ret=0;
if(L<=m)
ret=(ret+query(L, R, lson))%mod;
if(R>m)
ret=(ret+query(L, R, rson))%mod;
return ret%mod;
}
void update(int L, int R, int l, int r, int rt)
{
if(num[rt])
return ;
if(l==r)
{
LL cur=(sum[rt]*sum[rt])%mod;
if(sum[rt]==cur)
num[rt]=1;
sum[rt]=cur;
return ;
}
int m=(l+r)>>1;
if(L<=m)
update(L, R, lson);
if(R>m)
update(L, R, rson);
pushup(rt);
}
int main()
{
int t, ca=1;
scanf("%d", &t);
while(t--)
{
int n, m;
scanf("%d%d", &n, &m);
build(1, n, 1);
printf("Case #%d:\n", ca++);
LL ans=0;
while(m--)
{
int l, r;
scanf("%d%d", &l, &r);
ans=(ans+query(l, r, 1, n, 1))%mod;
//            printf("%I64d\n", ans);
out(ans);
puts("");
update(l, r, 1, n, 1);
}
}
return 0;
}


G++
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: