题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4578

题目:

题意:n个数初始值为0,进行四种操作:1.将区间内的数字加c;2.将区间内的数字乘c;3.将区间内的数字变成c;4.询问区间内的元素的p次方和。

思路:这个题真的肝到死,找bug贼难受。我们用cnt1来记录一次方和,cnt2记录二次方和,cnt3记录三次方和。

代码实现如下:

 #include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long ll;
typedef unsigned long long ull; #define lson i<<1
#define rson i<<1|1
#define bug printf("*********\n");
#define FIN freopen("D://code//in.txt", "r", stdin);
#define debug(x) cout<<"["<<x<<"]" <<endl;
#define IO ios::sync_with_stdio(false),cin.tie(0); const double eps = 1e-;
const int mod = ;
const int maxn = 1e5 + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f; inline int read() {//读入挂
int ret = , c, f = ;
for(c = getchar(); !(isdigit(c) || c == '-'); c = getchar());
if(c == '-') f = -, c = getchar();
for(; isdigit(c); c = getchar()) ret = ret * + c - '';
if(f < ) ret = -ret;
return ret;
} int n, q, op, x, y, z; struct node {
int l, r;
ll cnt1, cnt2, cnt3, lazy1, lazy2, lazy3, len; //cnt1=siga(ax+b), cnt2=sigs(ax+b)^2,cnt3=siga(ax+b)^3
//lazy1标记加b,lazy2标记乘a,lazy3标记赋值c
}segtree[maxn*]; void push_up(int i) {
segtree[i].cnt1 = (segtree[lson].cnt1 + segtree[rson].cnt1) % mod;
segtree[i].cnt2 = (segtree[lson].cnt2 + segtree[rson].cnt2) % mod;
segtree[i].cnt3 = (segtree[lson].cnt3 + segtree[rson].cnt3) % mod;
} void push_down(int i){
if(segtree[i].lazy3){
ll tmp = segtree[i].lazy3*segtree[i].lazy3%mod*segtree[i].lazy3%mod;
segtree[lson].lazy1=segtree[rson].lazy1=;
segtree[lson].lazy2=segtree[rson].lazy2=;
segtree[lson].lazy3=segtree[rson].lazy3=segtree[i].lazy3; segtree[lson].cnt3 = (segtree[lson].r - segtree[lson].l + )*tmp%mod;
segtree[rson].cnt3 = (segtree[rson].r - segtree[rson].l + )*tmp%mod; segtree[lson].cnt2 =(segtree[lson].r - segtree[lson].l + )*segtree[i].lazy3%mod*segtree[i].lazy3%mod;
segtree[rson].cnt2 = (segtree[rson].r - segtree[rson].l + )*segtree[i].lazy3%mod*segtree[i].lazy3%mod; segtree[lson].cnt1 =(segtree[lson].r - segtree[lson].l + )*segtree[i].lazy3%mod;
segtree[rson].cnt1 = (segtree[rson].r - segtree[rson].l + )*segtree[i].lazy3%mod; segtree[i].lazy3 = ;
}
if(segtree[i].lazy1!=||segtree[i].lazy2!=){
ll add = segtree[i].lazy1, mul = segtree[i].lazy2;
ll l1=segtree[lson].cnt1,l2=segtree[lson].cnt2,l3=segtree[lson].cnt3;
ll r1=segtree[rson].cnt1,r2=segtree[rson].cnt2,r3=segtree[rson].cnt3;
ll tmp = mul*mul%mod*mul%mod; segtree[lson].lazy1=(segtree[lson].lazy1*mul%mod+add)%mod;
segtree[rson].lazy1=(segtree[rson].lazy1*mul%mod+add)%mod;
segtree[lson].lazy2=segtree[lson].lazy2*mul%mod;
segtree[rson].lazy2=segtree[rson].lazy2*mul%mod; segtree[lson].cnt3=(segtree[lson].cnt3*tmp%mod + add*add%mod*add%mod*(segtree[lson].r - segtree[i].l + )%mod + *segtree[lson].cnt2*mul%mod*mul%mod*add%mod + *segtree[lson].cnt1*mul%mod*add%mod*add%mod)%mod;
segtree[rson].cnt3=(segtree[rson].cnt3*tmp%mod + add*add%mod*add%mod*(segtree[rson].r - segtree[rson].l + )%mod + *segtree[rson].cnt2*mul%mod*mul%mod*add%mod + *segtree[rson].cnt1*mul%mod*add%mod*add%mod)%mod; segtree[lson].cnt2=(segtree[lson].cnt2*mul%mod*mul%mod + add*add%mod*(segtree[lson].r - segtree[i].l + )%mod + *mul*add*segtree[lson].cnt1)%mod;
segtree[rson].cnt2=(segtree[rson].cnt2*mul%mod*mul%mod + add*add%mod*(segtree[rson].r - segtree[rson].l + )%mod + *mul*add*segtree[rson].cnt1)%mod; segtree[lson].cnt1=(segtree[lson].cnt1*mul+add*(segtree[lson].r - segtree[i].l + ))%mod;
segtree[rson].cnt1=(segtree[rson].cnt1*mul+add*(segtree[rson].r - segtree[rson].l + ))%mod; segtree[i].lazy1 = ;segtree[i].lazy2 = ;
}
} void build(int i, int l, int r) {
segtree[i].l = l, segtree[i].r = r;
segtree[i].cnt1 = segtree[i].cnt2 = segtree[i].cnt3 = ;
segtree[i].lazy1 = segtree[i].lazy3 = ;
segtree[i].lazy2 = ;
if(l == r) return;
int mid = (l + r) >> ;
build(lson, l, mid);
build(rson, mid + , r);
push_up(i);
} void update(int i, int l, int r, ll c, int op) {
if(segtree[i].l == l && segtree[i].r == r) {
if(op == ) {
segtree[i].cnt1 = c % mod * (segtree[i].r - segtree[i].l + ) % mod;
segtree[i].cnt2 = c * c % mod * (segtree[i].r - segtree[i].l + ) % mod;
segtree[i].cnt3 = c * c % mod * c % mod * (segtree[i].r - segtree[i].l + ) % mod;
segtree[i].lazy3 = c;
segtree[i].lazy2 = ;
segtree[i].lazy1 = ;
return;
} else if(op == ) {
segtree[i].cnt1 = c * segtree[i].cnt1 % mod;
segtree[i].cnt2 = c * c % mod * segtree[i].cnt2 % mod;
segtree[i].cnt3 = c * c % mod * c %mod * segtree[i].cnt3 % mod;
segtree[i].lazy2 = segtree[i].lazy2 * c % mod;
segtree[i].lazy1 = segtree[i].lazy1 * c % mod;
return;
} else {
segtree[i].lazy1 = (c + segtree[i].lazy1) % mod;
ll sum1 = segtree[i].cnt1, sum2 = segtree[i].cnt2, sum3 = segtree[i].cnt3;
segtree[i].cnt1 = (sum1 + c * (segtree[i].r - segtree[i].l + )) % mod;
segtree[i].cnt2 = ((sum2 % mod + * c % mod * sum1 % mod) % mod + c * c % mod * (segtree[i].r - segtree[i].l + ) % mod) % mod;
segtree[i].cnt3 = ((sum3 % mod + * c % mod * (sum2 + sum1 * c) % mod) % mod + c * c % mod * c * (segtree[i].r - segtree[i].l + ) % mod) % mod;
return;
}
}
push_down(i);
int mid = (segtree[i].l + segtree[i].r) >> ;
if(l > mid) update(rson, l, r, c, op);
else if(r <= mid) update(lson, l, r, c, op);
else {
update(lson, l, mid, c, op);
update(rson, mid + , r, c, op);
}
push_up(i);
} ll query(int i, int l, int r, int op) {
if(segtree[i].l == l && segtree[i].r == r) {
if(op == ) return segtree[i].cnt1;
if(op == ) return segtree[i].cnt2;
if(op == ) return segtree[i].cnt3;
}
push_down(i);
int mid = (segtree[i].l + segtree[i].r) >> ;
if(l > mid) return query(rson, l, r, op);
else if(r <= mid) return query(lson, l, r, op);
else {
return (query(lson, l, mid, op) + query(rson, mid + , r, op)) % mod;
}
} int main() {
//FIN;
while(~scanf("%d%d", &n, &q)) {
if(n == && q == ) break;
build(, , n);
while(q--) {
scanf("%d%d%d%d", &op, &x, &y, &z);
if(op == ) {
printf("%lld\n", query(, x, y, z));
} else {
z %= mod;
update(, x, y, z, op);
}
}
}
return ;
}

Transformation(线段树+HDU4578+多种操作+鬼畜的代码)的更多相关文章

  1. Sequence operation(线段树区间多种操作)

    Sequence operation Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  2. 线段树区间更新操作及Lazy思想(详解)

    此题题意很好懂:  给你N个数,Q个操作,操作有两种,‘Q a b ’是询问a~b这段数的和,‘C a b c’是把a~b这段数都加上c. 需要用到线段树的,update:成段增减,query:区间求 ...

  3. hdu 3436 线段树 一顿操作

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  4. HDU-4578 Transformation(线段树的多种区间操作)

    http://acm.hdu.edu.cn/showproblem.php?pid=4578 Time Limit: 15000/8000 MS (Java/Others)    Memory Lim ...

  5. hdu 4578 Transformation 线段树多种操作裸题

    自己写了一个带结构体的WA了7.8次 但是测了几组小数据都对..感觉问题应该出在模运算那里.写完这波题解去对拍一下. 以后线段树绝不写struct!一般的struct都带上l,r 但是一条线段的长度确 ...

  6. Transformation 线段树好题 好题 (独立写出来对线段树不容易)

    Transformation Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others)T ...

  7. HDU 4578 Transformation --线段树,好题

    题意: 给一个序列,初始全为0,然后有4种操作: 1. 给区间[L,R]所有值+c 2.给区间[L,R]所有值乘c 3.设置区间[L,R]所有值为c 4.查询[L,R]的p次方和(1<=p< ...

  8. POJ2528 线段树的区间操作

    首先应该对该[0,10000000]进行离散化 即先将点集进行排序,然后从小到大缩小其中的间距,使得最后点数不会超过2*n 然后就是线段树操作 只需进行染色,然后最后用nlgn进行一个个查询颜色记录即 ...

  9. CodeForces 914DBash and a Tough Math Puzzle(线段树的骚操作)

    D. Bash and a Tough Math Puzzle time limit per test 2.5 seconds memory limit per test 256 megabytes ...

随机推荐

  1. phpshell提权

    实际操作中可以在webshell用udf.dll提权,用函数的上传文件功能上传文件到启动目录,再用shut函数重起系统.(目前没成功过,有 机会本地测试一下,先记录在这了).如果是英文版的系统,启动目 ...

  2. ZigBee设备入网流程之关联方式

    ZigBee设备入网流程 ZigBee设备入网有关联方式和直接方式两种,我所熟悉的是关联方式,这也是最常用的方式. 关联方式 step1 设备发出Beacon Request 设备会在预先设置的几个信 ...

  3. xpath教程一---简单的标签搜索

    工具 Python3版本 lxml库[优点是解析快] HTML代码块[从网络中获取或者自己杜撰一个] requests[推荐安装,从网页上获取网页代码练手,再好不过了] 讲解 网页代码都是成对的标签, ...

  4. C# 压缩组件介绍与入门

    1.前言 作为吉日嘎拉权限管理系统最早的一批学习版用户,学了不少东西,在群里面也结识了很多朋友,更重要的是闲余时间,大家都发布很多可靠的外包工作.这次也是由于吉日嘎拉发布了一个有关“压缩文件损坏检测” ...

  5. codesandbox

    codesandbox https://codesandbox.io https://codesandbox.io/dashboard https://codesandbox.io/dashboard ...

  6. [剑指Offer] 45.扑克牌顺子

    题目描述 LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决 ...

  7. Windows下BMP位图格式介绍

    BMP图片,是Bitmap(位图)的简称,它是windows下显示图片的基本格式.在windows下任何格式的图片文件(包括视频播放)都要转化为位图才能显示出来.各种格式的图片文件也都是在位图格式的基 ...

  8. Bellman—Ford算法思想

    ---恢复内容开始--- Bellman—Ford算法能在更普遍的情况下(存在负权边)解决单源点最短路径问题.对于给定的带权(有向或无向)图G=(V,E),其源点为s,加权函数w是边集E的映射.对图G ...

  9. 协程简介-异步IO

    协程 1. 协程,又称微线程,纤程.协程是用户自己控制的,CPU根本不知道协程的存在,CPU只认识线程. 2. 线程切换的时候,会保存在CPU的寄存器里面. 协程切换的时候,却都是由用户自己的实现的. ...

  10. 洛谷 P1653 猴子 解题报告

    P1653 猴子 题目描述 有N只猴子,第一只尾巴挂在树上,剩下的N-1只,要么被其他的猴子抓住,要么抓住了其他的猴子,要么两者均有.当然一只猴子最多抓两只另外的猴子.现在给出这N只猴子抓与被抓的信息 ...