Mo team learning summary

Small Z socks (HYSBZ-2038)

As an undisciplined life of people, the small Z every morning takes a long time to find one pair from a pile of colorful socks to wear. Finally one day, the small Z can no longer tolerate this annoying process to find socks, so he decided resigned ...... Specifically, this small Z N socks numbered from 1 to N, and from the number L to R (L although small Z does not care two pair of socks is not complete, even two socks do not care whether either side, he is very concerned about the color of socks, after all, wearing two different colored socks will be very embarrassing. your task is to He told the small Z, how old he is able to get the same probability of socks, two colors, of course, hope that this small Z probability as high as possible, so he could ask more (L, R) in order to facilitate their choice.

Ideas: Template title

An interval \ ([l, r] \ ) answer:
\ [{\ sum_ {I appears as color} sum [i] \ cdot ( [i] sum -1) / 2} \ over {C_ {r -l + 1} ^ 2} \ ]

  1. Sort of inquiry
    1. \ ([L, r] \) , to \ (L \) number where the block is a first key, r is the second keyword in ascending order.
  2. Maintenance of violence molecule can be part of the answer
  3. The answer can be found in the numerator and denominator while about 2 out, after molecular expansion becomes \ ([i] sum \ cdot sum [i] - sum [i] \) can be found for all i, \ ([i] SUM \) and it will become \ (R & lt. 1-L + \) , so we only need to maintain all \ (sum [i] \) square and can
#include <iostream>
#include <algorithm>
#include <math.h>
#include <cstdio>
using namespace std;
const int N = 50010;
typedef long long ll;
int a[N],be[N],n,m;
ll res = 0,sum[N];
struct node{
    int l,r,id;
    ll A,B;
}q[N];
//如果在同一块,则按照右端点排序,否则按照左端点
bool cmp1(node a,node b){
    return be[a.l] == be[b.l] ? a.r < b.r : a.l < b.l;
}
bool cmp(node a,node b){
    return a.id < b.id;
}
ll gcd(ll a,ll b){return b == 0 ? a : gcd(b,a%b);}
ll S(ll x){return x * x;}
//先减去上一次的影响,修改后再重新加新的影响
void move(int pos,int add){res -= S(sum[a[pos]]);sum[a[pos]] += add;res += S(sum[a[pos]]);}
int main(){
    scanf("%d%d",&n,&m);
    int base = sqrt(n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);q[i].id = i;
        be[i] = (i-1) / base + 1;//be[i]即i在第几块
    }
    for(int i=1;i<=m;i++)scanf("%d%d",&q[i].l,&q[i].r);
    sort(q+1,q+1+m,cmp1);
    int l = 1,r = 0;
    res = 0;//res为当点询问区间内出现的所有颜色的个数平方和
    for(int i=1;i<=m;i++){
        //暴力调整区间,维护res
        while(l < q[i].l)move(l++,-1);
        while(l > q[i].l)move(--l,1);
        while(r < q[i].r)move(++r,1);
        while(r > q[i].r)move(r--,-1);
        if(l == r){
            q[i].A = 0;q[i].B = 1;continue;
        }
        q[i].A  = res - (r - l + 1);//计算答案分子部分
        q[i].B = 1ll * (r - l + 1) * (r - l);//分母部分
        ll g = gcd(q[i].A,q[i].B);//约分
        q[i].A /= g;
        q[i].B /= g;
    }
    sort(q+1,q+1+m,cmp);
    for(int i=1;i<=m;i++){
        printf("%lld/%lld\n",q[i].A,q[i].B);
    }
    return 0;
}

Ordinary Mo optimization team

After the interrogation can be found in the first block has been processed, the position r should be particularly rearward, but when moving to the next block after, r may move forward a lot, such as asking

//第一个块
1 50
2 100
//第二个块
12 13
14 100

After completion of [2100] the interrogation, r from 100-> 13 and then from 13 -> 100. This is clearly not as good as 100> 100, 100 -> 13.

How to optimize?

r collation between two adjacent opposite to

I.e. odd block in ascending order, in descending order of the even faster

Result Memory Time
Accepted 3456 kb 1840 ms
Accepted 3456 kb 1392 ms

The following is optimized.

bool cmp1(node a,node b){
    return be[a.l] == be[b.l] ? 
        (be[a.l]&1 ? a.r < b.r : a.r > b.r)
        : a.l < b.l;
}

Mo team with modifications

Do consider the general repair team to join modifications do if modification operations can \ (O (1) \) application and revocation (but also to maintain the current range of answers), it can \ (O (n ^ {5 \ over 3 }) \) find the answers to all inquiries within complexity.

Implementation: After the offline sort, order traversal inquiry, the first time the transfer to the current inquiry of time, and then transfer the same team as ordinary mo intervals.

Sorting methods: block length is set to \ (S_1, S_2 \) , in accordance with ( \ (\ lfloor {L \ over S_1} \ rfloor \ {R & lt lfloor \ over S_2} \ rfloor, T \) ) triad small to large order, which \ (t \) represents this moment experienced before asking several modification operations

Complexity Analysis: Considering the interrogation sequence in each piece, each asking the same keywords within twelve pieces. In this small, time \ (T \) Change up \ (m \) , for each challenge, \ (L, R & lt \) a maximum change \ (S_1, S_2 \) , the right total \ (n ^ 2 \ over {S_1, S_2} \) such blocks, the complexity of the transition between adjacent blocks is \ (O (n-) \) , the total complexity is

\(O(mS_1+mS_2+{n^2m\over S_1S_2}+{n^3\over S_1S_2})\)

When \ (n, m \) when the same order, take \ (S_1 = S_2 = n ^ {2 \ over 3} \) can be optimal complexity when \ (n O (^ {5 \ over 3}) \ )

int l = 0, r = 0, t = 0, nowAns = 0;

inline void move(int pos, int sign) {
    // update nowAns
}

inline void moveTime(int t, int sign) {
    // apply or revoke modification
    // update nowAns
}

void solve() {
    BLOCK_SIZE = int(ceil(pow(n, 2.0 / 3)));
    sort(querys, querys + m);
    for (int i = 0; i < q1; ++i) {
        const query q = querys[i];
        while (t < q.t) moveTime(t++, 1);
        while (t > q.t) moveTime(--t, -1);
        while (l < q.l) move(l++, -1);
        while (l > q.l) move(--l, 1);
        while (r < q.r) move(r++, 1);
        while (r > q.r) move(--r, -1);
        ans[q.id] = nowAns;
    }
}

Guess you like

Origin www.cnblogs.com/1625--H/p/11329586.html