HDU 3074 Multiply game【线段树||zkw线段树||扩展gcd*乘法逆元||欧拉定理】
来源:互联网 发布:杜特软件下载 编辑:程序博客网 时间:2024/06/05 21:56
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2818 Accepted Submission(s): 1002
Problem Description
Tired of playing computer games, alpc23 is planning to play a game on numbers. Because plus and subtraction is too easy for this gay, he wants to do some multiplication in a number sequence. After playing it a few times, he has found it is also too boring. So he plan to do a more challenge job: he wants to change several numbers in this sequence and also work out the multiplication of all the number in a subsequence of the whole sequence.
To be a friend of this gay, you have been invented by him to play this interesting game with him. Of course, you need to work out the answers faster than him to get a free lunch, He he…
Input
The first line is the number of case T (T<=10).
For each test case, the first line is the length of sequence n (n<=50000), the second line has n numbers, they are the initial n numbers of the sequence a1,a2, …,an,
Then the third line is the number of operation q (q<=50000), from the fourth line to the q+3 line are the description of the q operations. They are the one of the two forms:
0 k1 k2; you need to work out the multiplication of the subsequence from k1 to k2, inclusive. (1<=k1<=k2<=n)
1 k p; the kth number of the sequence has been change to p. (1<=k<=n)
You can assume that all the numbers before and after the replacement are no larger than 1 million.
Output
For each of the first operation, you need to output the answer of multiplication in each line, because the answer can be very large, so can only output the answer after mod 1000000007.
Sample Input
1
6
1 2 4 5 6 3
3
0 2 5
1 3 7
0 2 5
Sample Output
240
420
Source
2009 Multi-University Training Contest 17 - Host by NUDT
Recommend
lcy | We have carefully selected several similar problems for you: 3069 3070 3071 3072 3073
题意:给出一个区间,查询区间乘积,单点更新。
对于线段树的掌握不够熟练,慢慢补出所有题解!
普通线段树(AC):
#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;#define rt x<<1|1#define lt x<<1const int maxn = 8 * 5 * 1e4;#define ll long long intconst ll p = 1e9 + 7;ll sum[maxn], a[maxn / 8];void init(){}void build(int x, int L, int R){ if (L == R) { sum[x] = a[L]; sum[x] %= p;//(sum[x]=a[L])%=p } else { int mid = (L + R) / 2; build(lt, L, mid); build(rt, mid + 1, R); sum[x] = sum[lt] * sum[rt];//(sum[x]=sum[lt]*sum[rt])%=p; sum[x] %= p; }}void change(int x, int L, int R, int i, ll k){ if (L == R&&R == i) { sum[x] = k; sum[x] %= p; } else { int mid = (L + R) / 2; if (i <= mid) change(lt, L, mid, i, k); if (mid < i) change(rt, mid + 1, R, i, k); sum[x] = sum[lt] * sum[rt]; sum[x] %= p; }}ll query(int x, int L, int R, int LL, int RR){ ll ans = 1; if (LL <= L&&RR >= R) { ans = sum[x]; ans %= p; } else { int mid = (L + R) / 2; if (LL <= mid) { ans *= query(lt, L, mid, LL, RR); ans %= p; } if (mid < RR) { ans *= query(rt, mid + 1, R, LL, RR); ans %= p; } } return ans;}int main(){ int t; scanf("%d", &t); while (t--) { int n; scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%lld", &a[i]); } build(1, 1, n); int q; scanf("%d", &q); while (q--) { int t1, t2, t3; scanf("%d %d %d", &t1, &t2, &t3); if (t1) { change(1, 1, n, t2, 1ll * t3); } else { ll ans = 0; ans = query(1, 1, n, t2, t3); printf("%lld\n", ans); } } } return 0;}
扩展欧几里得(TLE):
顺带着 扩展gcd求乘法逆元的模板。
数据加强过了,再研究研究有没有可以突破的地方。
#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<algorithm>using namespace std;#define rt x<<1|1#define lt x<<1#define ll long long intconst int maxn = 5 * 1e4 + 10;const ll low(ll x) { return x&-x; }const ll p = 1e9 + 7;ll f[maxn], a[maxn];ll t, x, y, n, m, X, Y, Z;void init() { for (ll i = 0; i <= n; i++) f[i] = 1;}/* a*x + b*y = gcd *//*扩展欧几里得推导 呱唧呱唧呱唧*//* a%b = a - (a/b)*b */ //取余函数/* gcd = b*x1 + (a-(a/b)*b)*y1 = b*x1 + a*y1 – (a/b)*b*y1 = a*y1 + b*(x1 – a/b*y1) */ /* x = y1 y = x1 – a / b*y1 */int e_gcd(int a, int b, int &x, int &y){ if (b == 0) { x = 1; y = 0; return a; } int ans = e_gcd(b, a%b, x, y); int temp = x; x = y; y = temp - a / b*y; /* x = y1 y = x1 – a / b*y1 */ return ans;}int cal(int a, int m)//求逆元{ int x, y; int gcd = e_gcd(a, m, x, y); if (1 % gcd != 0) return -1; x *= 1 / gcd; m = abs(m); int ans = (x%m + m) % m; return ans;}ll mod(const ll a){ return (a%p + p) % p;}ll inv(ll x, ll m){ if (x == 1) return x; return inv(m%x, m)*(m - m / x) % m;}ll sum(ll x){ ll tot = 1; for (ll i = x; i; i -= low(i)) tot = mod(tot*f[i]); return tot;}void change(ll x, ll y){ for (ll i = x; i <= n; i += low(i)) f[i] = mod(f[i] * y);}int main(){ //int t; scanf("%lld", &t); while (t--) { //int n; scanf("%lld", &n); init(); for (ll i = 1; i <= n; i++) { scanf("%lld", &a[i]); change(i, a[i]); } scanf("%lld", &m); while (m--) { scanf("%lld %lld %lld", &X, &Y, &Z); if (X) { x = inv(a[Y], p); change(Y, mod(Z*x)); a[Y] = Z; } else { x = inv(sum(Y - 1), p); printf("%lld\n", mod(sum(Z)*x)); } } } return 0;}
- HDU 3074 Multiply game【线段树||zkw线段树||扩展gcd*乘法逆元||欧拉定理】
- HDU 3074 线段树 Multiply game
- hdu 3074 Multiply game (线段树)
- HDU 3074 Multiply game (线段树)
- hdu 3074 Multiply game(线段树)
- hdu 3074 Multiply game(线段树)
- bzoj3813(线段树+乘法逆元+欧拉函数)
- hdu 3074 Multiply game(模板级线段树)
- hdu 3074 Multiply game(线段树模版)
- HDU 3074 Multiply game(线段树 单点更新)
- HDU 1754 I Hate It (线段树初步point的修改)HDU 3074 Multiply game (增加同余定理)
- BZOJ 3813 奇数国 欧拉函数+线段树+乘法逆元
- 3813: 奇数国 线段树+线性筛素数+欧拉函数+乘法逆元+压位
- hdu 1166 敌兵布阵 (zkw线段树)
- HDU3074 Multiply game 解题报告--线段树
- zkw线段树 运用
- 【zkw线段树】ural1855
- ZKW线段树
- bzoj3993 [SDOI2015]星际战争 二分答案+网络流检验
- Solr4.7.2+tomcat+ZooKeeper 部署SolrCloud 之 删除Collection
- 递归和迭代的区别
- 6.16
- java使用google开源工具实现图片压缩
- HDU 3074 Multiply game【线段树||zkw线段树||扩展gcd*乘法逆元||欧拉定理】
- python实现贝叶斯算法
- 《SVM笔记系列之五》软间隔线性支持向量机
- express-session
- 仿京东实现使用味豆支付
- 对于服务器返回的JSON字符串,如果 jQuery 异步请求没做类型说明,或者以字符串方式接受,那么需要做一次对象化处理
- 超大数据快速导入MySQL
- 记Redis那坑人的HGETALL
- json基础