Qingbei escort sprint text1t1 count
How many unordered binary groups are there $ (X ?, ? Y) $ meet $ XY \ equiv 1? (Mod? P) $, $0 \ Leq x <p ?, ? 0 \ Leq Y <p $
Solution:
You are not mistaken. This is T1 of day1, a naked mathematical problem.
Subtask 1: Enumerate $ O (P ^ 2) $ binary groups, select the qualified groups, and re-calculate them. subtask 2: in the sense of "p $, A number X has a reverse element, and only when $ gcd (x, P) = 1 $. If $ x $ has a reverse element, there is only one reverse element for $ x $. Set $1 $ to $ P? In 1 $, there are $ S $ mutual quality numbers. Considering that the $ S $ number is a binary group consisting of their inverse elements, these tuples must meet the condition, so if you consider removing duplicates, you can find that if $ XY then 1 (mod? P), X \ NEQ y $, then $ (x, y) $ and $ (Y, x) $ will each appear in the $ S $ binary groups, that is, it is calculated once more. Set to meet $ x ^ 2 limit 1 (mod? P) $ x $ has $ T $. It is easy to calculate the answer: $ \ frac {S + t} {2} $. The brute-force enumeration calculates $ S $ and $ T $, and the complexity $ O (nlogn) $ subtask 3: If you perform the second subtask, you are not far from the AC question. In fact, subtask 2 is a pseudo-positive solution, and its limitation is that it is too slow to find $ S $. Therefore, the problem we want to solve in subtask 3 is actually how to quickly find $ S $. So we introduce the Euler function to solve this problem. Then the problem is converted into the problem of finding the value of $ S = \ PHI (p) $ when $ p \ geq 1 $. The value of $ \ PHI (p) $ can be solved in linear screening. Code:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define ll long long#define N 50000005#define M 1000005using namespace std;int n,prime[M];int num,phi[N];bool flag[N];inline void open_judge() { freopen("count.in","r",stdin); freopen("count.out","w",stdout);}int main() { open_judge(); scanf("%d",&n); flag[1] = 1; phi[1] = 1; for(int i = 2 ; i <= n ; i++) { if(!flag[i]) { prime[++num] = i; phi[i] = i - 1; } for(int j = 1 ; j <= num && prime[j] * i <= n ; j++) { flag[prime[j] * i] = 1; if(i % prime[j] == 0) { phi[i * prime[j]] = phi[i] * prime[j]; break; } phi[i * prime[j]] = phi[i] * phi[prime[j]]; } } for(long long i = 1 ; i <= n ; i++) if(i * i % n == 1) phi[n]++; printf("%d\n",phi[n] / 2); return 0;}
T2 color
Given N points on the plane, you need to dye each point into black or white. After dyeing, the absolute value of the black and white dot quantity difference must be less than or equal to 1 on any line parallel to the coordinate axis.
Solution: subtask 1: enumeration of $2 ^ N $ dyeing solutions and judgment. Subtask $2-> 4 $: first, discretization the coordinates. Consider a bipartite graph. A vertex (X, Y) is considered to have an edge connected between the X vertex of the left half side and the Y vertex of the right half side. The problem is that the number of black and white edges connected to each vertex must be less than or equal to 1. Since each vertex has an even number of degrees, a Unicom block can be covered by an Euler loop. The adjacent edges on the Euler's road are stained with different colors. In this way, the numbers of black edges and white edges connected to each vertex must be equal. Code:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct Data { int v; int p;}data[500005];struct Edge { int to; int next;}e[1000005];int n,m,cnt=1,head[1000005],d[1000005];int x[500005],y[500005],num,ans[500005];bool flag[500005];void add_edge(int u,int v) { e[++cnt].to = v; e[cnt].next = head[u]; head[u] = cnt;}inline bool cmp(Data a,Data b) { return a.v < b.v;}void lisan() { for(int i = 1 ; i <= n ; i++) { data[i].p = i; data[i].v = x[i]; } sort(data+1,data+n+1,cmp); data[0].v=-1; for(int i = 1 ; i <= n ; i++) { if(data[i].v != data[i-1].v) num++; x[data[i].p] = num; } for(int i = 1 ; i <= n ; i++) { data[i].p = i; data[i].v = y[i]; } sort(data+1,data+n+1,cmp); data[0].v = -1; for(int i = 1 ; i <= n ; i++) { if(data[i].v != data[i-1].v) num++; y[data[i].p] = num; }}void dfs(int node,bool last) { while(1) { bool ff = 1; for(int&hd = head[node] ; hd ; hd = e[hd].next) { if(flag[hd>>1]) continue; flag[hd>>1] = 1; d[node]--; d[e[hd].to]--; ans[hd>>1] = !last; node = e[hd].to; last = !last; ff = 0; break; } if(ff) break; }}inline int read() { char c=getchar(); int t=0; while(c>'9'||c<'0')c=getchar(); while(c>='0'&&c<='9') {t=t*10+c-'0';c=getchar();} return t;}inline void open_judge() { freopen("color.in","r",stdin); freopen("color.out","w",stdout);}int main() { open_judge(); n = read(); for(int i = 1 ; i <= n ; i++) { x[i] = read(); y[i] = read(); } lisan(); for(int i = 1 ; i <= n ; i++) { d[x[i]]++,d[y[i]]++; add_edge(x[i],y[i]); add_edge(y[i],x[i]); } for(int i = 1 ; i <= num ; i++) { if(d[i] & 1) { d[i]++,d[num+1]++; add_edge(i , num + 1); add_edge(num + 1 , i); } } num++; memset(ans,-1,sizeof(ans)); for(int i = 1 ; i <= num ; i++) { while(d[i]) dfs(i,0); } for(int i = 1 ; i <= n ; i++) printf("%d ",ans[i]); printf("\n"); return 0;}
T3 Sequence
A sequence of $ n (n \ Leq 5 \ times 10 ^ 5) $ numbers is given. The value of an interval is the product of the maximum value of the minimum value in the interval. Evaluate the sum of values in all intervals. Evaluate the Modulo for $998244353 $.
Solution: subtask 1: $ O (N ^ 2) $ brute force. Subtask 2: subtask 2. If the value and subinterval of the interval [L; R] are being considered, set the subscript of the maximum value in the range $ [L, R] $ to $ mid $. Consider the value and range of the Left endpoint in $ [L, mid] $ and the right endpoint in $ [mid, R] $. Their internal maximum value is $ A _ {mid} $. Suffix $ min $ for $ [L, mid] $ and prefix $ min $ for $ [mid, R] $. The result is recorded as $ Mn [I] $. $ L \ Leq I \ Leq mid $ Mn [I] = min ^ {mid}
{I = 1} a_ I. When mid <I \ Leq R, Mn [I] = min ^ r{I = mid} a_ I $. Enumerate the left endpoint $ I $. Because the $ Mn $ in the right half is monotonous, there must be a demarcation point $ p $, make $ J \ Leq p $ Mn [J] \ geq Mn [I] $, $ j> P $ Mn [J] <Mn [I] $. Because the $ Mn $ in the left half is monotonous, the moving direction of the demarcation point $ p $ remains unchanged when the left endpoint $ I $ is moved. In this way, it is easy to find the demarcation point $ p $ for each left endpoint $ I $. In addition, you can find the prefix and sum of $ Mn $ to $ O (1) $ and find the left endpoint at $ I $, and the right endpoint at $ [mid, r] $. Then recursively calculate the range $ [L, mid? 1] $ and $ [Mid + 1, R] $. Total complexity $ O (nlogn) $. Subtask 3: there are only 10 types of data. Therefore, when the left endpoint is fixed, the maximum value is up to 10 types. That is, the maximum value of the right endpoint in a certain range is the same, and the maximum value of this range is 10, the minimum value is the same. Considering the maximum and minimum values, we can know that when the left endpoint is fixed, the maximum and minimum values of the right endpoint within a certain range are the same, and this range can have at most 20. Moving the left endpoint, maintaining these intervals with a monotonous stack, complexity $ O (N? 20) $. Subtask 4: $ O (nlog ^ 2 N) $... Subtask 5 (standard calculation): similar to subtask2, $ mid =? \ Frac {L + R} {2 }? $. Perform operations similar to the minimum value (You may want to mark the result of the prefix/suffix $ Max $ as $ MX [I] $). We can find the demarcation point of the maximum value $ q $. In addition to the $ Mn $ prefix and the $ MX $ prefix and the $ Mn \ times MX $ prefix are obtained. $ P $ and $ q $ divide the right half into three intervals and calculate the three intervals respectively. You can use the obtained prefix and $ O (1) $ to calculate the value and value of the right endpoint in a range. Then, recursively calculate the Left and Right Parts. The total time complexity is $ O (nlogn) $. Code:
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#define ll long long#define MOD 998244353#define N 500005using namespace std;ll n,a[N],ans,maxl[N];ll maxr[N],minl[N],minr[N];ll sum[N],sum_minl[N],sum_maxl[N];void work(int l,int r) { if(l > r)return; if(l == r) { ans = (ans + a[l] * a[r]) % MOD; return; } int mid = (l+r) >> 1; work(l , mid - 1); work(mid + 1 , r); ll s = 0; maxl[0] = maxr[0] = minl[0] = minr[0] = a[mid]; for(int i = mid + 1 ; i <= r ; i++) { maxr[i - mid] = max(maxr[i - mid - 1] , a[i]); minr[i - mid] = min(minr[i - mid - 1] , a[i]); } for(int i = mid - 1 ; i >= l ; i--) { maxl[mid - i] = max(maxl[mid - i - 1] , a[i]); minl[mid - i] = min(minl[mid - i - 1] , a[i]); } sum[mid - l + 1] = 0; for(int i = l ; i <= mid ; i++) { sum[mid - i] = (sum[mid - i + 1] + minl[mid - i] * maxl[mid - i]) % MOD; sum_minl[mid - i] = (sum_minl[mid - i + 1] + minl[mid - i]) % MOD; sum_maxl[mid - i] = (sum_maxl[mid - i + 1] + maxl[mid - i]) % MOD; } int now_minl = 0 , now_maxl = 0; for(int i = 0 ; i <= r - mid ; i++) { while(now_minl <= mid - l && minl[now_minl] >= minr[i]) now_minl++; while(now_maxl <= mid - l && maxl[now_maxl] <= maxr[i]) now_maxl++; ans = (ans + minr[i] * maxr[i] % MOD * min(now_minl , now_maxl)) % MOD; ans = ans + sum[max(now_minl , now_maxl)]; if(now_minl < now_maxl) ans = (ans + (sum_minl[now_minl] - sum_minl[now_maxl] + MOD) * maxr[i]) % MOD; else ans = (ans + (sum_maxl[now_maxl] - sum_maxl[now_minl] + MOD) * minr[i]) % MOD; }}inline void open_judge() { freopen("sequence.in","r",stdin); freopen("sequence.out","w",stdout);}int main() { open_judge(); scanf("%lld",&n); for(int i = 1 ; i <= n ; i++) scanf("%lld",&a[i]); work(1,n); printf("%lld\n" , ans % MOD); return 0;}
Qingbei escort class (1)