hdu 5475 (线段树)
An easy problem
Time Limit: 8000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2770 Accepted Submission(s): 1034
Problem Description
One day, a useless calculator was being built by Kuros. Let's assume that number X is showed on the screen of calculator. At first, X = 1. This calculator only supports two types of operation.
1. multiply X with a number.
2. divide X with a number which was multiplied before.
After each operation, please output the number X modulo M.
1. multiply X with a number.
2. divide X with a number which was multiplied before.
After each operation, please output the number X modulo M.
Input
The first line is an integer T(1≤T≤10), indicating the number of test cases.
For each test case, the first line are two integers Q and M. Q is the number of operations and M is described above. (1≤Q≤105,1≤M≤109)
The next Q lines, each line starts with an integer x indicating the type of operation.
if x is 1, an integer y is given, indicating the number to multiply. (0<y≤109)
if x is 2, an integer n is given. The calculator will divide the number which is multiplied in the nth operation. (the nth operation must be a type 1 operation.)
It's guaranteed that in type 2 operation, there won't be two same n.
For each test case, the first line are two integers Q and M. Q is the number of operations and M is described above. (1≤Q≤105,1≤M≤109)
The next Q lines, each line starts with an integer x indicating the type of operation.
if x is 1, an integer y is given, indicating the number to multiply. (0<y≤109)
if x is 2, an integer n is given. The calculator will divide the number which is multiplied in the nth operation. (the nth operation must be a type 1 operation.)
It's guaranteed that in type 2 operation, there won't be two same n.
Output
For each test case, the first line, please output "Case #x:" and x is the id of the test cases starting from 1.
Then Q lines follow, each line please output an answer showed by the calculator.
Then Q lines follow, each line please output an answer showed by the calculator.
Sample Input
1
10 1000000000
1 2
2 1
1 2
1 10
2 3
2 4
1 6
1 7
1 12
2 7
Sample Output
Case #1: 2 1 2 20 10 1 6 42 504 84
思路:
之前以为可以直接逆元,后面想起来逆元是要两个互质的数,后面想到了题目就是提示你用线段树,只要用建个线段树就好了。
假如第i次操作 ,x = 1;是第一种操作,那么只要根据修改第x个叶子结点将他修改为y。
x=2,只要将第y个叶子节点修改为1,
每一次操作都求出根节点的值就好了。
实现代码:
#include<bits/stdc++.h> using namespace std; #define ll long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mid int m = (l + r) >> 1 const int M = 1e5+10; ll sum[M<<2]; ll m; void pushup(int rt){ sum[rt] = (sum[rt<<1]*sum[rt<<1|1])%m; } void update(int p,int c,int l,int r,int rt){ if(l == r){ sum[rt] = c; return ; } mid; if(p <= m) update(p,c,lson); if(p > m) update(p,c,rson); pushup(rt); } void build(int l,int r,int rt){ if(l == r){ sum[rt] = 1; return ; } mid; 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]; } mid; ll ret = 1; if(L <= m) ret= (ret*query(L,R,lson))%m; if(R > m) ret= (ret*query(L,R,rson))%m; return ret; } int main() { ll t,n,x; ll y; ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); while(cin>>t){ int t1 = t; while(t--){ ll ans = 1; cin>>n>>m; build(1,n,1); //cout<<2<<endl; cout<<"Case #"<<t1-t<<":"<<endl; for(int i = 1;i <= n;i ++){ cin>>x>>y; if(x==1){ update(i,y,1,n,1); cout<<query(1,n,1,n,1)<<endl; } else{ update(y,1,1,n,1); cout<<query(1,n,1,n,1)<<endl; } } memset(sum,0,sizeof(sum)); } } return 0; }