您的位置:首页 > 其它

【线段树】 HDOJ 5152 A Strange Problem

2014-12-28 20:00 218 查看
BC的官方题解已经写的很清楚了。。。。

#include <iostream>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 50005
#define maxm 400005
#define eps 1e-10
//#define mod 2333333
#define INF 0x3f3f3f3f
#define PI (acos(-1.0))
#define lowbit(x) (x&(-x))
#define mp make_pair
#define ls o<<1
#define rs o<<1 | 1
#define lson o<<1, L, mid
#define rson o<<1 | 1, mid+1, R
//#pragma comment(linker, "/STACK:16777216")
typedef long long LL;
typedef unsigned long long ULL;
//typedef int LL;
using namespace std;
LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}
LL powmod(LL a, LL b, LL mod){LL res=1%mod,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}
// head

int mo[20] = {2333333,2196720,580608,165888,55296,18432,6144,2048,1024,512,256,128,64,32,16,8,4,2,1};
LL pow2[33];
vector<LL> v[maxn];
LL sum[maxn << 2];
LL add[maxn << 2];
LL a[maxn];
int n, m;

const int MOD = 2333333;

void read(void)
{
pow2[0] = 1;
for(int i = 1; i <= 30; i++) pow2[i] = pow2[i-1] * 2;
for(int i = 1; i <= n; i++) scanf("%I64d", &a[i]);
}

void pushup(int o);

void build(int o, int L, int R)
{
add[o] = 0;
if(L == R)  {
sum[o] = a[L];
v[L].clear();
v[L].push_back(a[L]);
return;
}
int mid = (L + R) >> 1;
build(lson);
build(rson);
pushup(o);
}

void pushup(int o)
{
sum[o] = (sum[ls] + sum[rs]) % MOD;
}

void pushdown(int o, int L, int R)
{
if(add[o]) {
int mid = (L + R) >> 1;
sum[ls] = (sum[ls] + add[o] * (mid - L + 1) % MOD) % MOD;
sum[rs] = (sum[rs] + add[o] * (R - mid) % MOD) % MOD;
add[ls] += add[o];
add[rs] += add[o];
add[o] = 0;
}
}

LL query(int o, int L, int R, int ql, int qr)
{
if(ql <= L && qr >= R) return sum[o];
pushdown(o, L, R);
int mid = (L + R) >> 1;
LL ans = 0;
if(ql <= mid) ans = (ans + query(lson, ql, qr)) % MOD;
if(qr > mid) ans = (ans + query(rson, ql, qr)) % MOD;
pushup(o);
return ans;
}

void update(int o, int L, int R, int ql, int qr, LL x)
{
if(ql <= L && qr >= R) {
sum[o] = ((R - L + 1) * x % MOD + sum[o]) % MOD;
add[o] += x;
return;
}
pushdown(o, L, R);
int mid = (L + R) >> 1;
if(ql <= mid) update(lson, ql, qr, x);
if(qr > mid) update(rson, ql, qr, x);
pushup(o);
}

LL calc(vector<LL> &vec)
{
if(vec.size() > 18) {
LL res = 1;
int now = 18;
for(int i = vec.size() - 18; i < vec.size(); i++) {
res = (powmod(2, res, mo[now]) + vec[i]) % mo[now] + mo[now];
now--;
}
return res % MOD;
}
else {
LL res = vec[0];
int now = vec.size() - 1;
int flag = 0;
if(res >= mo[now]) {
flag = 1;
res = res % mo[now] + mo[now];
}
now--;
for(int i = 1; i < vec.size(); i++) {
if(flag) res = (powmod(2, res, mo[now]) + vec[i]) % mo[now] + mo[now];
else if(res >= 30) res = (powmod(2, res, mo[now]) + vec[i]) % mo[now] + mo[now], flag = 1;
else if(pow2[res] >= mo[now]) res = (powmod(2, res, mo[now]) + vec[i]) % mo[now] + mo[now], flag = 1;
else {
res = pow2[res] + vec[i];
if(res >= mo[now]) {
flag = 1;
res = res % mo[now] + mo[now];
}
}
now--;
}
return res % MOD;
}
}

void modify(int o, int L, int R, LL x)
{
if(L == R) {
if(add[o]) {
v[L][v[L].size() - 1] += add[o];
add[o] = 0;
}
v[L].push_back(0);
sum[o] = calc(v[L]);
return;
}
pushdown(o, L, R);
LL mid = (L + R) >> 1;
if(x <= mid) modify(lson, x);
else modify(rson, x);
pushup(o);
}

void work(void)
{
int ql, qr, k;
LL x;
build(1, 1, n);
while(m--) {
scanf("%d", &k);
if(k == 1) {
scanf("%d%d", &ql, &qr);
printf("%I64d\n", query(1, 1, n, ql, qr));
}
if(k == 2) {
scanf("%I64d", &x);
modify(1, 1, n, x);
}
if(k == 3) {
scanf("%d%d%I64d", &ql, &qr, &x);
update(1, 1, n, ql, qr, x);
}
}
}

int main(void)
{
while(scanf("%d%d", &n, &m)!=EOF) {
read();
work();
}

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