https://acm.ecnu.edu.cn/contest/173/problem/E/

分析:

考虑这样一种情况,如果对一个点连续地做几次乘操作,那么之后紧跟着的除操作只需要将乘操作的次数减少即可。(因为如果当前是乘于的最小素因子后面肯定也是除上这个)

那么对这个点的操作将会变成连续的一段乘或者除。如果一段除操作之后出现了乘操作,那只能在一段除之后做一段乘操作了,因为执行了除之后minprime可能会变化。(很显然)

所以最后对这个点的操作将会变成一段除操作跟着一段乘操作。

那么就可以利用线段树维护这样一段操作的除乘的个数了。线段树每个节点维护两个信息:除操作个数,乘操作个数

收获:对线段树的强大操作再一次的认识了!

#include<bits/stdc++.h>
using namespace std;
#define lc ((o) << 1)
#define rc ((o) << 1 | 1)
#define ll long long
const int N = ;
const int MOD = 1e9+;
int Mul[N<<],Div[N<<],a[N]; void powndown(int o , int l , int r)
{
if(Mul[o] || Div[o])
{
if(Mul[lc]>=Div[o])
{
Mul[lc]-=Div[o];
}
else
{
Div[lc]+=(Div[o]-Mul[lc]);
Mul[lc]=;
} if(Mul[rc]>=Div[o])
{
Mul[rc]-=Div[o];
}
else
{
Div[rc]+=(Div[o]-Mul[rc]);
Mul[rc]=;
}
Mul[lc]+=Mul[o];
Mul[rc]+=Mul[o];
Mul[o]=Div[o]=;
}
}
void update(int o, int l, int r, int L, int R, int tree[], int op)
{
if(L <= l && R >= r)
{
if(op == )tree[o]++;
else
{
if(Mul[o])Mul[o]--;
else tree[o]++;
}
return;
}
powndown(o, l, r);
int m = (l + r) / ;
if(L <= m)update(lc, l, m, L, R, tree, op);
if(R > m)update(rc, m + , r, L, R, tree, op);
} void query(int o, int l, int r, int x, int& divnum, int& mulnum)
{
if(l == r)
{
divnum = Div[o];
mulnum = Mul[o];
return;
}
powndown(o, l, r);
int m = (l + r) / ;
if(x <= m)query(lc, l, m, x, divnum, mulnum);
else query(rc, m + , r, x, divnum, mulnum);
}
int tot;
bool vis[N];
int pr[N];
void init()
{
tot=;
for(int i= ; i<=N ; i++)
{
if(vis[i]==)
{
pr[++tot]=i;
//cout<<i<<" "<<pr[10]<<endl;
for(int j=*i;j<=N;j+=i)
vis[j]=;
}
}
}
vector<int>FA[N];
ll POW(ll x , ll y)
{
ll ans=;
while(y)
{
if(y&) ans=ans*x%MOD;
y>>=;
x=x*x%MOD;
}
return ans;
}
int main()
{ int n,m;scanf("%d%d",&n,&m);
init();
//cout<<pr[1]<<" "<<pr[2]<<endl;
for(int i= ; i<=n ; i++)
{
scanf("%d",&a[i]);
int x=a[i]; for(int j= ; j<=tot&&pr[j]*pr[j]<=x;j++)
{
while(x%pr[j]==)
{
x/=pr[j];
FA[i].push_back(pr[j]);
} }
if(x!=) FA[i].push_back(x);
// cout<<FA[i].size()<<endl;
} while(m--)
{
int op,l,r;scanf("%d",&op);
if(op==)
{
scanf("%d%d",&l,&r);
update(,,n,l,r,Mul,);
}
else if(op==)
{
scanf("%d%d",&l,&r);
update(,,n,l,r,Div,);
}
else
{
scanf("%d",&l);
int numMul=,numDiv=;
query(,,n,l,numDiv,numMul);
// cout<<numDiv<<" "<<numMul<<endl;
// cout<<FA[l].size()<<endl;
if(numDiv>=FA[l].size())
{
puts("");
}
else
{
ll ans=,tmp=FA[l][numDiv]; for(int i=numDiv ; i<FA[l].size();i++)
ans=(ans*(1ll*FA[l][i]))%MOD;
ans=(ans*POW(tmp,numMul))%MOD;
printf("%lld\n",ans);
}
}
}
}

“美登杯”上海市高校大学生程序设计 E. 小花梨的数组 (线段树)的更多相关文章

  1. “美登杯”上海市高校大学生程序设计 C. 小花梨判连通 (并查集+map)

    Problem C C . 小 花梨 判连通 时间限制:2000ms 空间限制:512MB Description 小花梨给出

  2. “美登杯”上海市高校大学生程序设计邀请赛 **D. 小花梨的取石子游戏**

    "美登杯"上海市高校大学生程序设计邀请赛 (华东理工大学) D. 小花梨的取石子游戏 Description 小花梨有

  3. 美登杯”上海市高校大学生程序设计邀请赛 Problem E 、 小 花梨 的数组 (线段树)

    Problem E E . 小 花梨 的数组 时间限制:1000ms 空间限制:512MB Description 小花梨得到了一个长度为

  4. “美登杯”上海市高校大学生程序设计赛B. 小花梨的三角形(模拟,实现)

    题目链接:https://acm.ecnu.edu.cn/contest/173/problem/B/#report9 Problem B B . 小 花梨 的 三角形 时间限制:1000ms 空间限 ...

  5. “美登杯”上海市高校大学生程序设计邀请赛 (华东理工大学) E 小花梨的数组 线段树

    题意 分析 预处理出每个数的最小素因子,首先可以知道\(minprime(x*minprime(x))=minprime(x)\),我们用线段树维护区间最大值\(mx[p]\),注意这里的最大值并不是 ...

  6. "字节跳动杯"2018中国大学生程序设计竞赛-女生专场 Solution

    A - 口算训练 题意:询问 $[L, R]$区间内 的所有数的乘积是否是D的倍数 思路:考虑分解质因数 显然,一个数$x > \sqrt{x} 的质因子只有一个$ 那么我们考虑将小于$\sqr ...

  7. "字节跳动杯"2018中国大学生程序设计竞赛-女生专场

    口算训练 #include <iostream> #include <algorithm> #include <cstring> #include <cstd ...

  8. fzu 2105 Digits Count ( 线段树 ) from 第三届福建省大学生程序设计竞赛

    http://acm.fzu.edu.cn/problem.php?pid=2105 Problem Description Given N integers A={A[0],A[1],...,A[N ...

  9. 第十一届GPCT杯大学生程序设计大赛完美闭幕

    刚刚过去的周六(6月7号)是今年高考的第一天,同一时候也是GPCT杯大学生程序设计大赛颁奖的日子,以下我们用图文再回想一下本次大赛颁奖的过程. 评审过程的一些花絮<感谢各位评审这些天的付出!&g ...

随机推荐

  1. 【ABAP系列】SAP ABAP ALV合计或者小计 添加自定义文本

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP ABAP ALV合计或者小计 ...

  2. mooc-IDEA 收藏位置和文件--003

    六.IntelliJ IDEA -收藏位置和文件(类/函数) 1.收藏自己喜欢的文件---代码 添加一个Favorites列表 定义名称 Help->Find Action... 选择Add t ...

  3. python基础-5 冒泡排序、递归

    上节总结 一.上节内容补充回顾 1.lambda func = lambda x,y: 9+x 参数: x,y 函数体:9+x ==> return 9+x func: 函数名 def func ...

  4. github廖雪峰git

    gitHub地址: https://github.com/DickyQie/Tool-use/tree/git-learning-document

  5. wikioi 2144 分步二进制枚举+map记录

    题目描写叙述 Description 有n个砝码,如今要称一个质量为m的物体,请问最少须要挑出几个砝码来称? 注意一个砝码最多仅仅能挑一次 输入描写叙述 Input Description 第一行两个 ...

  6. 前后台交互实例二:前台通过django在数据库里面增删改查数据

    url(r'^userinfo/', views.userinfo), url(r'^userdetail-(?P<nid>\d+)/', views.userdetail), url(r ...

  7. 攻防世界--re1-100

    测试文件:https://adworld.xctf.org.cn/media/task/attachments/dc14f9a05f2846249336a84aecaf18a2.zip 1.准备 获取 ...

  8. JavaScript基础3——使用Button提交表单

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. javascript Math取整&获取随机数

    1.方法介绍 Math.ceil(n) 上取整,大于等于n返回与它最接近的整数 Math.floor(n) 下取整,小于等于n返回与它最接近的整数 Math.round(n) 四舍五入取整 Math. ...

  10. vue.js(13)--按键修饰符

    v-on监听事件时可添加按键修饰符 <!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` --> <input v-on:keyup.enter=&q ...