【HDOJ】3071 Gcd & Lcm game

刚开始看这个题目,觉得没法做。关键点是数据小于100。因此,可以枚举所有小于100的素因子进行位压缩。
gcd就是求最小值,lcm就是求最大值。c++有时候超时,g++800ms。线段树可解。

  1 /* 3071 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <algorithm>
 12 #include <cstdio>
 13 #include <cmath>
 14 #include <ctime>
 15 #include <cstring>
 16 #include <climits>
 17 #include <cctype>
 18 #include <cassert>
 19 #include <functional>
 20 #include <iterator>
 21 #include <iomanip>
 22 using namespace std;
 23 //#pragma comment(linker,"/STACK:102400000,1024000")
 24 
 25 #define sti                set<int>
 26 #define stpii            set<pair<int, int> >
 27 #define mpii            map<int,int>
 28 #define vi                vector<int>
 29 #define pii                pair<int,int>
 30 #define vpii            vector<pair<int,int> >
 31 #define rep(i, a, n)     for (int i=a;i<n;++i)
 32 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 33 #define clr                clear
 34 #define pb                 push_back
 35 #define mp                 make_pair
 36 #define fir                first
 37 #define sec                second
 38 #define all(x)             (x).begin(),(x).end()
 39 #define SZ(x)             ((int)(x).size())
 40 #define lson            l, mid, rt<<1
 41 #define rson            mid+1, r, rt<<1|1
 42 #define ui32            unsigned int
 43 
 44 typedef struct {
 45     ui32 mx, mn;
 46 } node_t;
 47 
 48 int factor[25] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
 49 int width[25] = {3,3,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
 50 int shift[25] = {28,25,23,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
 51 int mask[25] =  {7,7,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
 52 const int maxn = 1e5+5;
 53 int M[25][8];
 54 node_t nd[maxn<<2];
 55 int L, R, mod;
 56 
 57 void init() {
 58     rep(i, 0, 25) {
 59         M[i][0] = 1;
 60         rep(j, 1, mask[i]+1)
 61             M[i][j] = M[i][j-1] * factor[i];
 62     }
 63 }
 64 
 65 int getVal(int x) {
 66     int ret = 1, tmp;
 67     
 68     for (int i=24; i>=0; --i) {
 69         tmp = M[i][x&mask[i]];
 70         ret = ret * tmp % mod;
 71         x >>= width[i];
 72     }
 73     
 74     return ret;
 75 }
 76 
 77 ui32 calc(int x) {
 78     ui32 ret = 0, tmp;
 79     
 80     rep(i, 0, 25) {
 81         ret <<= width[i];
 82         tmp = 0;
 83         if (x%factor[i] == 0) {
 84             while (x%factor[i] == 0) {
 85                 ++tmp;
 86                 x /= factor[i];
 87             }
 88         }
 89         ret += tmp;
 90     }
 91     
 92     return ret;
 93 }
 94 
 95 ui32 mymax(ui32 x, ui32 y) {
 96     ui32 ret = max(x&0x70000000, y&0x70000000)\
 97             | max(x&0x0e000000, y&0x0e000000)\
 98             | max(x&0x01800000, y&0x01800000)\
 99             | max(x&0x00600000, y&0x00600000)\
100             | ((x&0x001fffff) | (y&0x001fffff));
101     return ret;
102 }
103 
104 ui32 mymin(ui32 x, ui32 y) {
105     ui32 ret = min(x&0x70000000, y&0x70000000)\
106             | min(x&0x0e000000, y&0x0e000000)\
107             | min(x&0x01800000, y&0x01800000)\
108             | min(x&0x00600000, y&0x00600000)\
109             | ((x&0x001fffff) & (y&0x001fffff));
110     return ret;
111 }
112 
113 inline void PushUp(int rt) {
114     int lb = rt << 1;
115     int rb = lb |  1;
116     
117     nd[rt].mx =    mymax(nd[lb].mx, nd[rb].mx);
118     nd[rt].mn =    mymin(nd[lb].mn, nd[rb].mn);
119 }
120 
121 void Build(int l, int r, int rt) {
122     if (l == r) {
123         int x;
124         scanf("%d", &x);
125         nd[rt].mx = nd[rt].mn = calc(x);
126         return ;
127     }
128     
129     int mid = (l + r) >> 1;
130     
131     Build(lson);
132     Build(rson);
133     PushUp(rt);
134 }
135 
136 ui32 Query_mx(int l, int r, int rt) {
137     if (L<=l && R>=r) {
138         return nd[rt].mx;
139     }
140     
141     int mid = (l + r) >> 1;
142     ui32 ret;
143     
144     if (R <= mid) {
145         ret = Query_mx(lson);
146     } else if (L > mid) {
147         ret = Query_mx(rson);
148     } else {
149         ui32 ltmp = Query_mx(lson);
150         ui32 rtmp = Query_mx(rson);
151         ret = mymax(ltmp, rtmp);
152     }
153     
154     return ret;
155 }
156 
157 ui32 Query_mn(int l, int r, int rt) {
158     if (L<=l && R>=r) {
159         return nd[rt].mn;
160     }
161     
162     int mid = (l + r) >> 1;
163     ui32 ret;
164     
165     if (R <= mid) {
166         ret = Query_mn(lson);
167     } else if (L > mid) {
168         ret = Query_mn(rson);
169     } else {
170         ui32 ltmp = Query_mn(lson);
171         ui32 rtmp = Query_mn(rson);
172         ret = mymin(ltmp, rtmp);
173     }
174     
175     return ret;
176 }
177 
178 void Update(int k, int x, int l, int r, int rt) {
179     if (l == r) {
180         nd[rt].mx = nd[rt].mn = calc(x);
181         return ;
182     }
183     
184     int mid = (l + r) >> 1;
185     
186     if (k <= mid)
187         Update(k, x, lson);
188     else
189         Update(k, x, rson);
190     
191     PushUp(rt);
192 }
193 
194 int main() {
195     ios::sync_with_stdio(false);
196     #ifndef ONLINE_JUDGE
197         freopen("data.in", "r", stdin);
198         freopen("data.out", "w", stdout);
199     #endif
200     
201     int n, q;
202     char op[10];
203     int tmp, k;
204     int ans;
205     
206     init();
207     while (scanf("%d %d", &n, &q) != EOF) {
208         Build(1, n, 1);
209         while (q--) {
210             scanf("%s", op);
211             if (op[0] == 'L') {
212                 scanf("%d %d %d", &L, &R, &mod);
213                 tmp = Query_mx(1, n, 1);
214                 ans = getVal(tmp);
215                 printf("%d\n", ans);
216             } else if (op[0] == 'G') {
217                 scanf("%d %d %d", &L, &R, &mod);
218                 tmp = Query_mn(1, n, 1);
219                 ans = getVal(tmp);
220                 printf("%d\n", ans);
221             } else {
222                 scanf("%d %d", &k, &tmp);
223                 Update(k, tmp, 1, n, 1);
224             }
225         }
226     }
227     
228     #ifndef ONLINE_JUDGE
229         printf("time = %d.\n", (int)clock());
230     #endif
231     
232     return 0;
233 }

 

转载于:https://www.cnblogs.com/bombe1013/p/5080288.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值